The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
Changes 014
MANIFEST 40129
META.yml 1322
Makefile.PL 317
README 933
inc/Module/AutoInstall.pm 3385
inc/Module/Install/AuthorRequires.pm 038
inc/Module/Install/AuthorTests.pm 059
inc/Module/Install/AutoInstall.pm 518
inc/Module/Install/Base.pm 2639
inc/Module/Install/Can.pm 1110
inc/Module/Install/Fetch.pm 66
inc/Module/Install/Include.pm 44
inc/Module/Install/Makefile.pm 155358
inc/Module/Install/Metadata.pm 244636
inc/Module/Install/Win32.pm 87
inc/Module/Install/WriteAll.pm 3050
inc/Module/Install.pm 202387
lib/Catalyst/Engine/Apache.pm 1019
lib/Catalyst/Engine/Apache.pm.rej 049
lib/Catalyst/Engine/Apache2/MP19.pm 218
lib/Catalyst/Engine/Apache2/MP20.pm 137
lib/Catalyst/Engine/Apache2.pm 11
lib/Catalyst/Engine/Apache2.pm.rej 017
t/00compiles.t 09
t/02pod.t 70
t/03podcoverage.t 70
t/author/live_component_controller_action_action.t 0110
t/author/live_component_controller_action_auto.t 0136
t/author/live_component_controller_action_begin.t 053
t/author/live_component_controller_action_chained.t 0831
t/author/live_component_controller_action_default.t 096
t/author/live_component_controller_action_detach.t 0100
t/author/live_component_controller_action_end.t 054
t/author/live_component_controller_action_forward.t 0238
t/author/live_component_controller_action_global.t 083
t/author/live_component_controller_action_index.t 0100
t/author/live_component_controller_action_inheritance.t 0119
t/author/live_component_controller_action_local.t 0138
t/author/live_component_controller_action_multipath.t 071
t/author/live_component_controller_action_path.t 0127
t/author/live_component_controller_action_private.t 089
t/author/live_component_controller_action_regexp.t 0106
t/author/live_component_controller_action_streaming.t 072
t/author/live_component_controller_args.t 098
t/author/live_engine_request_body.t 077
t/author/live_engine_request_body_demand.t 066
t/author/live_engine_request_cookies.t 045
t/author/live_engine_request_headers.t 071
t/author/live_engine_request_parameters.t 0129
t/author/live_engine_request_uploads.t 0247
t/author/live_engine_request_uri.t 0121
t/author/live_engine_response_cookies.t 073
t/author/live_engine_response_errors.t 060
t/author/live_engine_response_headers.t 058
t/author/live_engine_response_large.t 027
t/author/live_engine_response_redirect.t 048
t/author/live_engine_response_status.t 055
t/author/live_engine_setup_basics.t 019
t/author/live_engine_setup_plugins.t 016
t/author/live_fork.t 060
t/author/live_loop.t 023
t/author/live_plugin_loaded.t 023
t/author/live_priorities.t 081
t/author/live_recursion.t 025
t/author/notabs.t 010
t/author/pod.t 08
t/author/podcoverage.t 016
t/lib/ACLTestApp/Controller/Root.pm 018
t/lib/ACLTestApp.pm 026
t/lib/CDICompatTestPlugin.pm 042
t/lib/Catalyst/Action/TestAfter.pm 11
t/lib/Catalyst/Action/TestBefore.pm 11
t/lib/Catalyst/Plugin/Test/Deprecated.pm 017
t/lib/Catalyst/Plugin/Test/Errors.pm 23
t/lib/Catalyst/Plugin/Test/Headers.pm 23
t/lib/Catalyst/Plugin/Test/MangleDollarUnderScore.pm 016
t/lib/Catalyst/Plugin/Test/Plugin.pm 713
t/lib/Catalyst/Script/Bar.pm 09
t/lib/Catalyst/Script/Baz.pm 016
t/lib/Catalyst/Script/CompileTest.pm 016
t/lib/ChainedActionsApp/Controller/Root.pm 063
t/lib/ChainedActionsApp.pm 021
t/lib/DeprecatedActionsInAppClassTestApp.pm 030
t/lib/DeprecatedTestApp/C/Root.pm 018
t/lib/DeprecatedTestApp.pm 014
t/lib/NullPackage.pm 07
t/lib/PluginTestApp/Controller/Root.pm 062
t/lib/PluginTestApp.pm 467
t/lib/ScriptTestApp/Script/Bar.pm 09
t/lib/ScriptTestApp/Script/CompileTest.pm 07
t/lib/ScriptTestApp/Script/Foo.pm 09
t/lib/TestApp/Action/TestBefore.pm 11
t/lib/TestApp/Action/TestExtraArgsAction.pm 017
t/lib/TestApp/Action/TestMyAction.pm 14
t/lib/TestApp/Controller/Action/Action.pm 026
t/lib/TestApp/Controller/Action/Chained/ArgsOrder.pm 035
t/lib/TestApp/Controller/Action/Chained/CaptureArgs.pm 066
t/lib/TestApp/Controller/Action/Chained/Foo.pm 21
t/lib/TestApp/Controller/Action/Chained/ParentChain/Relative.pm 010
t/lib/TestApp/Controller/Action/Chained/ParentChain.pm 012
t/lib/TestApp/Controller/Action/Chained/PathPrefix.pm 012
t/lib/TestApp/Controller/Action/Chained.pm 138
t/lib/TestApp/Controller/Action/Forward.pm 010
t/lib/TestApp/Controller/Action/ForwardTo.pm 011
t/lib/TestApp/Controller/Action/Go.pm 0102
t/lib/TestApp/Controller/Action/Inheritance.pm 012
t/lib/TestApp/Controller/Action/Local.pm 05
t/lib/TestApp/Controller/Action/Path.pm 06
t/lib/TestApp/Controller/Action/Private.pm 55
t/lib/TestApp/Controller/Action/Regexp.pm 014
t/lib/TestApp/Controller/Action/Streaming.pm 214
t/lib/TestApp/Controller/Action/Streaming.pm.rej 017
t/lib/TestApp/Controller/Action/TestRelative.pm 020
t/lib/TestApp/Controller/Action/Visit.pm 0104
t/lib/TestApp/Controller/Anon.pm 039
t/lib/TestApp/Controller/Args.pm 32
t/lib/TestApp/Controller/Attributes.pm 030
t/lib/TestApp/Controller/ContextClosure.pm 029
t/lib/TestApp/Controller/Dump.pm 910
t/lib/TestApp/Controller/Engine/Request/URI.pm 226
t/lib/TestApp/Controller/Engine/Request/Uploads.pm 11
t/lib/TestApp/Controller/Engine/Response/Cookies.pm 55
t/lib/TestApp/Controller/Engine/Response/Errors.pm 11
t/lib/TestApp/Controller/Engine/Response/Headers.pm 11
t/lib/TestApp/Controller/Engine/Response/Large.pm 11
t/lib/TestApp/Controller/Engine/Response/Print.pm 025
t/lib/TestApp/Controller/Engine/Response/Redirect.pm 11
t/lib/TestApp/Controller/Engine/Response/Status.pm 11
t/lib/TestApp/Controller/Fork.pm 12
t/lib/TestApp/Controller/Immutable/HardToReload.pm 030
t/lib/TestApp/Controller/Immutable.pm 05
t/lib/TestApp/Controller/Index.pm 11
t/lib/TestApp/Controller/Keyword.pm 018
t/lib/TestApp/Controller/Moose/MethodModifiers.pm 010
t/lib/TestApp/Controller/Moose/NoAttributes.pm 016
t/lib/TestApp/Controller/Moose.pm 033
t/lib/TestApp/Controller/Priorities/MultiMethod.pm 02
t/lib/TestApp/Controller/Priorities/loc_vs_index.pm 11
t/lib/TestApp/Controller/Priorities/locre_vs_index.pm 11
t/lib/TestApp/Controller/Priorities/path_vs_index.pm 11
t/lib/TestApp/Controller/Priorities/re_vs_index.pm 11
t/lib/TestApp/Controller/Priorities.pm 11
t/lib/TestApp/Controller/Root.pm 164
t/lib/TestApp/DispatchType/CustomPostLoad.pm 010
t/lib/TestApp/DispatchType/CustomPreLoad.pm 010
t/lib/TestApp/Model/ClosuresInConfig.pm 012
t/lib/TestApp/Model/Foo.pm 04
t/lib/TestApp/Model/Generating.pm 022
t/lib/TestApp/Model.pm 016
t/lib/TestApp/Plugin/AddDispatchTypes.pm 026
t/lib/TestApp/Plugin/ParameterizedRole.pm 018
t/lib/TestApp/RequestBaseBug.pm 014
t/lib/TestApp/Role.pm 015
t/lib/TestApp/View/Dump/Body.pm 011
t/lib/TestApp/View/Dump/Env.pm 012
t/lib/TestApp/View/Dump/Parameters.pm 110
t/lib/TestApp/View/Dump.pm 1219
t/lib/TestApp.pm 3157
t/lib/TestAppBadlyImmutable.pm 012
t/lib/TestAppClassExceptionSimpleTest.pm 021
t/lib/TestAppDoubleAutoBug/Controller/Root.pm 022
t/lib/TestAppDoubleAutoBug.pm 122
t/lib/TestAppEncoding/Controller/Root.pm 048
t/lib/TestAppEncoding.pm 011
t/lib/TestAppIndexDefault/Controller/Default.pm 015
t/lib/TestAppIndexDefault/Controller/IndexChained.pm 012
t/lib/TestAppIndexDefault/Controller/IndexPrivate.pm 010
t/lib/TestAppIndexDefault/Controller/Root.pm 017
t/lib/TestAppIndexDefault.pm 08
t/lib/TestAppMatchSingleArg/Controller/Root.pm 024
t/lib/TestAppMatchSingleArg.pm 08
t/lib/TestAppMetaCompat/Controller/Base.pm 06
t/lib/TestAppMetaCompat/Controller/Books.pm 08
t/lib/TestAppMetaCompat.pm 08
t/lib/TestAppNonMooseController/Controller/Foo.pm 05
t/lib/TestAppNonMooseController/ControllerBase.pm 05
t/lib/TestAppNonMooseController.pm 08
t/lib/TestAppOnDemand/Controller/Body.pm 041
t/lib/TestAppOnDemand.pm 020
t/lib/TestAppOneView/Controller/Root.pm 034
t/lib/TestAppOneView/View/Dummy.pm 013
t/lib/TestAppOneView.pm 08
t/lib/TestAppPathBug.pm 028
t/lib/TestAppPluginWithConstructor/Controller/Root.pm 012
t/lib/TestAppPluginWithConstructor.pm 021
t/lib/TestAppShowInternalActions/Controller/Root.pm 019
t/lib/TestAppShowInternalActions.pm 020
t/lib/TestAppStats/Controller/Root.pm 016
t/lib/TestAppStats.pm 026
t/lib/TestAppToTestScripts.pm 014
t/lib/TestAppUnknownError.pm 022
t/lib/TestAppWithMeta/Controller/Root.pm 017
t/lib/TestAppWithMeta.pm 013
t/lib/TestPluginWithConstructor.pm 017
t/live_component_controller_action_action.t 1100
t/live_component_controller_action_auto.t 1360
t/live_component_controller_action_begin.t 530
t/live_component_controller_action_chained.t 8310
t/live_component_controller_action_default.t 960
t/live_component_controller_action_detach.t 1000
t/live_component_controller_action_end.t 540
t/live_component_controller_action_forward.t 2380
t/live_component_controller_action_global.t 830
t/live_component_controller_action_index.t 1000
t/live_component_controller_action_inheritance.t 1190
t/live_component_controller_action_local.t 1380
t/live_component_controller_action_multipath.t 710
t/live_component_controller_action_path.t 1270
t/live_component_controller_action_private.t 890
t/live_component_controller_action_regexp.t 1060
t/live_component_controller_action_streaming.t 720
t/live_component_controller_args.t 980
t/live_engine_request_body.t 770
t/live_engine_request_cookies.t 450
t/live_engine_request_headers.t 710
t/live_engine_request_parameters.t 1290
t/live_engine_request_uploads.t 2440
t/live_engine_request_uri.t 1210
t/live_engine_response_cookies.t 730
t/live_engine_response_errors.t 600
t/live_engine_response_headers.t 580
t/live_engine_response_large.t 270
t/live_engine_response_redirect.t 480
t/live_engine_response_status.t 550
t/live_engine_setup_basics.t 190
t/live_engine_setup_plugins.t 160
t/live_fork.t 600
t/live_loop.t 230
t/live_plugin_loaded.t 270
t/live_priorities.t 810
t/live_recursion.t 250
232 files changed (This is a version diff) 48678206
@@ -1,5 +1,19 @@
 This file documents the revision history for Catalyst::Engine::Apache.
 
+1.14
+        - No changes since dev release.
+
+1.13_01
+        - Update tests to pass again.
+        - Update tests to not throw warnings with newer versions of Catalyst.
+        - Fix $c->req->remote_user with this engine.
+        - Clarify use with non-standard ports.
+        - Fixes RT#61707, RT#61706, RT#61704, RT#36829
+
+1.13
+        - Workaround change in LWP that broke a cookie test (RT #40037)
+        - Update streaming test to latest 5.70
+
 1.12    2008-02-20 09:00:00
         - Fixed bug where %2b in query parameter is doubly decoded to ' ', instead of '+' 
           (Gavin Henry, Tatsuhiko Miyagawa)
@@ -1,6 +1,8 @@
 Changes
 inc/Module/AutoInstall.pm
 inc/Module/Install.pm
+inc/Module/Install/AuthorRequires.pm
+inc/Module/Install/AuthorTests.pm
 inc/Module/Install/AutoInstall.pm
 inc/Module/Install/Base.pm
 inc/Module/Install/Can.pm
@@ -11,26 +13,87 @@ inc/Module/Install/Metadata.pm
 inc/Module/Install/Win32.pm
 inc/Module/Install/WriteAll.pm
 lib/Catalyst/Engine/Apache.pm
+lib/Catalyst/Engine/Apache.pm.rej
 lib/Catalyst/Engine/Apache/MP13.pm
 lib/Catalyst/Engine/Apache2.pm
+lib/Catalyst/Engine/Apache2.pm.rej
 lib/Catalyst/Engine/Apache2/MP19.pm
 lib/Catalyst/Engine/Apache2/MP20.pm
 Makefile.PL
 MANIFEST			This list of files
 META.yml
 README
-t/02pod.t
-t/03podcoverage.t
+t/00compiles.t
+t/author/live_component_controller_action_action.t
+t/author/live_component_controller_action_auto.t
+t/author/live_component_controller_action_begin.t
+t/author/live_component_controller_action_chained.t
+t/author/live_component_controller_action_default.t
+t/author/live_component_controller_action_detach.t
+t/author/live_component_controller_action_end.t
+t/author/live_component_controller_action_forward.t
+t/author/live_component_controller_action_global.t
+t/author/live_component_controller_action_index.t
+t/author/live_component_controller_action_inheritance.t
+t/author/live_component_controller_action_local.t
+t/author/live_component_controller_action_multipath.t
+t/author/live_component_controller_action_path.t
+t/author/live_component_controller_action_private.t
+t/author/live_component_controller_action_regexp.t
+t/author/live_component_controller_action_streaming.t
+t/author/live_component_controller_args.t
+t/author/live_engine_request_body.t
+t/author/live_engine_request_body_demand.t
+t/author/live_engine_request_cookies.t
+t/author/live_engine_request_headers.t
+t/author/live_engine_request_parameters.t
+t/author/live_engine_request_uploads.t
+t/author/live_engine_request_uri.t
+t/author/live_engine_response_cookies.t
+t/author/live_engine_response_errors.t
+t/author/live_engine_response_headers.t
+t/author/live_engine_response_large.t
+t/author/live_engine_response_redirect.t
+t/author/live_engine_response_status.t
+t/author/live_engine_setup_basics.t
+t/author/live_engine_setup_plugins.t
+t/author/live_fork.t
+t/author/live_loop.t
+t/author/live_plugin_loaded.t
+t/author/live_priorities.t
+t/author/live_recursion.t
+t/author/notabs.t
+t/author/pod.t
+t/author/podcoverage.t
 t/catalyst_130pix.gif
 t/conf/extra.conf.in
+t/lib/ACLTestApp.pm
+t/lib/ACLTestApp/Controller/Root.pm
 t/lib/Catalyst/Action/TestAfter.pm
 t/lib/Catalyst/Action/TestBefore.pm
+t/lib/Catalyst/Plugin/Test/Deprecated.pm
 t/lib/Catalyst/Plugin/Test/Errors.pm
 t/lib/Catalyst/Plugin/Test/Headers.pm
+t/lib/Catalyst/Plugin/Test/MangleDollarUnderScore.pm
 t/lib/Catalyst/Plugin/Test/Plugin.pm
+t/lib/Catalyst/Script/Bar.pm
+t/lib/Catalyst/Script/Baz.pm
+t/lib/Catalyst/Script/CompileTest.pm
+t/lib/CDICompatTestPlugin.pm
+t/lib/ChainedActionsApp.pm
+t/lib/ChainedActionsApp/Controller/Root.pm
+t/lib/DeprecatedActionsInAppClassTestApp.pm
+t/lib/DeprecatedTestApp.pm
+t/lib/DeprecatedTestApp/C/Root.pm
+t/lib/NullPackage.pm
 t/lib/PluginTestApp.pm
+t/lib/PluginTestApp/Controller/Root.pm
+t/lib/ScriptTestApp/Script/Bar.pm
+t/lib/ScriptTestApp/Script/CompileTest.pm
+t/lib/ScriptTestApp/Script/Foo.pm
 t/lib/TestApp.pm
 t/lib/TestApp/Action/TestBefore.pm
+t/lib/TestApp/Action/TestExtraArgsAction.pm
 t/lib/TestApp/Action/TestMyAction.pm
 t/lib/TestApp/Controller/Action.pm
 t/lib/TestApp/Controller/Action/Action.pm
@@ -40,21 +103,27 @@ t/lib/TestApp/Controller/Action/Auto/Deep.pm
 t/lib/TestApp/Controller/Action/Auto/Default.pm
 t/lib/TestApp/Controller/Action/Begin.pm
 t/lib/TestApp/Controller/Action/Chained.pm
+t/lib/TestApp/Controller/Action/Chained/ArgsOrder.pm
 t/lib/TestApp/Controller/Action/Chained/Auto.pm
 t/lib/TestApp/Controller/Action/Chained/Auto/Bar.pm
 t/lib/TestApp/Controller/Action/Chained/Auto/Detach.pm
 t/lib/TestApp/Controller/Action/Chained/Auto/Foo.pm
 t/lib/TestApp/Controller/Action/Chained/Auto/Forward.pm
 t/lib/TestApp/Controller/Action/Chained/Bar.pm
+t/lib/TestApp/Controller/Action/Chained/CaptureArgs.pm
 t/lib/TestApp/Controller/Action/Chained/Foo.pm
 t/lib/TestApp/Controller/Action/Chained/ParentChain.pm
+t/lib/TestApp/Controller/Action/Chained/ParentChain/Relative.pm
 t/lib/TestApp/Controller/Action/Chained/PassedArgs.pm
+t/lib/TestApp/Controller/Action/Chained/PathPrefix.pm
 t/lib/TestApp/Controller/Action/Chained/Root.pm
 t/lib/TestApp/Controller/Action/Default.pm
 t/lib/TestApp/Controller/Action/Detach.pm
 t/lib/TestApp/Controller/Action/End.pm
 t/lib/TestApp/Controller/Action/Forward.pm
+t/lib/TestApp/Controller/Action/ForwardTo.pm
 t/lib/TestApp/Controller/Action/Global.pm
+t/lib/TestApp/Controller/Action/Go.pm
 t/lib/TestApp/Controller/Action/Index.pm
 t/lib/TestApp/Controller/Action/Inheritance.pm
 t/lib/TestApp/Controller/Action/Local.pm
@@ -62,9 +131,14 @@ t/lib/TestApp/Controller/Action/Path.pm
 t/lib/TestApp/Controller/Action/Private.pm
 t/lib/TestApp/Controller/Action/Regexp.pm
 t/lib/TestApp/Controller/Action/Streaming.pm
+t/lib/TestApp/Controller/Action/Streaming.pm.rej
 t/lib/TestApp/Controller/Action/TestMultipath.pm
 t/lib/TestApp/Controller/Action/TestRelative.pm
+t/lib/TestApp/Controller/Action/Visit.pm
+t/lib/TestApp/Controller/Anon.pm
 t/lib/TestApp/Controller/Args.pm
+t/lib/TestApp/Controller/Attributes.pm
+t/lib/TestApp/Controller/ContextClosure.pm
 t/lib/TestApp/Controller/Dump.pm
 t/lib/TestApp/Controller/Engine/Request/Uploads.pm
 t/lib/TestApp/Controller/Engine/Request/URI.pm
@@ -72,10 +146,17 @@ t/lib/TestApp/Controller/Engine/Response/Cookies.pm
 t/lib/TestApp/Controller/Engine/Response/Errors.pm
 t/lib/TestApp/Controller/Engine/Response/Headers.pm
 t/lib/TestApp/Controller/Engine/Response/Large.pm
+t/lib/TestApp/Controller/Engine/Response/Print.pm
 t/lib/TestApp/Controller/Engine/Response/Redirect.pm
 t/lib/TestApp/Controller/Engine/Response/Status.pm
 t/lib/TestApp/Controller/Fork.pm
+t/lib/TestApp/Controller/Immutable.pm
+t/lib/TestApp/Controller/Immutable/HardToReload.pm
 t/lib/TestApp/Controller/Index.pm
+t/lib/TestApp/Controller/Keyword.pm
+t/lib/TestApp/Controller/Moose.pm
+t/lib/TestApp/Controller/Moose/MethodModifiers.pm
+t/lib/TestApp/Controller/Moose/NoAttributes.pm
 t/lib/TestApp/Controller/Priorities.pm
 t/lib/TestApp/Controller/Priorities/loc_vs_index.pm
 t/lib/TestApp/Controller/Priorities/locre_vs_index.pm
@@ -83,55 +164,63 @@ t/lib/TestApp/Controller/Priorities/MultiMethod.pm
 t/lib/TestApp/Controller/Priorities/path_vs_index.pm
 t/lib/TestApp/Controller/Priorities/re_vs_index.pm
 t/lib/TestApp/Controller/Root.pm
+t/lib/TestApp/DispatchType/CustomPostLoad.pm
+t/lib/TestApp/DispatchType/CustomPreLoad.pm
+t/lib/TestApp/Model.pm
+t/lib/TestApp/Model/ClosuresInConfig.pm
 t/lib/TestApp/Model/Foo.pm
 t/lib/TestApp/Model/Foo/Bar.pm
+t/lib/TestApp/Model/Generating.pm
+t/lib/TestApp/Plugin/AddDispatchTypes.pm
 t/lib/TestApp/Plugin/FullyQualified.pm
+t/lib/TestApp/Plugin/ParameterizedRole.pm
+t/lib/TestApp/RequestBaseBug.pm
+t/lib/TestApp/Role.pm
 t/lib/TestApp/View/Dump.pm
-t/lib/TestApp/View/Dump/Parameters.pm
+t/lib/TestApp/View/Dump/Body.pm
+t/lib/TestApp/View/Dump/Env.pm
 t/lib/TestApp/View/Dump/Request.pm
 t/lib/TestApp/View/Dump/Response.pm
+t/lib/TestAppBadlyImmutable.pm
 t/lib/TestAppChainedAbsolutePathPart.pm
 t/lib/TestAppChainedAbsolutePathPart/Controller/Foo.pm
 t/lib/TestAppChainedRecursive.pm
 t/lib/TestAppChainedRecursive/Controller/Foo.pm
+t/lib/TestAppClassExceptionSimpleTest.pm
 t/lib/TestAppDoubleAutoBug.pm
-t/live_component_controller_action_action.t
-t/live_component_controller_action_auto.t
-t/live_component_controller_action_begin.t
-t/live_component_controller_action_chained.t
-t/live_component_controller_action_default.t
-t/live_component_controller_action_detach.t
-t/live_component_controller_action_end.t
-t/live_component_controller_action_forward.t
-t/live_component_controller_action_global.t
-t/live_component_controller_action_index.t
-t/live_component_controller_action_inheritance.t
-t/live_component_controller_action_local.t
-t/live_component_controller_action_multipath.t
-t/live_component_controller_action_path.t
-t/live_component_controller_action_private.t
-t/live_component_controller_action_regexp.t
-t/live_component_controller_action_streaming.t
-t/live_component_controller_args.t
-t/live_engine_request_body.t
-t/live_engine_request_cookies.t
-t/live_engine_request_headers.t
-t/live_engine_request_parameters.t
-t/live_engine_request_uploads.t
-t/live_engine_request_uri.t
-t/live_engine_response_cookies.t
-t/live_engine_response_errors.t
-t/live_engine_response_headers.t
-t/live_engine_response_large.t
-t/live_engine_response_redirect.t
-t/live_engine_response_status.t
-t/live_engine_setup_basics.t
-t/live_engine_setup_plugins.t
-t/live_fork.t
-t/live_loop.t
-t/live_plugin_loaded.t
-t/live_priorities.t
-t/live_recursion.t
+t/lib/TestAppDoubleAutoBug/Controller/Root.pm
+t/lib/TestAppEncoding.pm
+t/lib/TestAppEncoding/Controller/Root.pm
+t/lib/TestAppIndexDefault.pm
+t/lib/TestAppIndexDefault/Controller/Default.pm
+t/lib/TestAppIndexDefault/Controller/IndexChained.pm
+t/lib/TestAppIndexDefault/Controller/IndexPrivate.pm
+t/lib/TestAppIndexDefault/Controller/Root.pm
+t/lib/TestAppMatchSingleArg.pm
+t/lib/TestAppMatchSingleArg/Controller/Root.pm
+t/lib/TestAppMetaCompat.pm
+t/lib/TestAppMetaCompat/Controller/Base.pm
+t/lib/TestAppMetaCompat/Controller/Books.pm
+t/lib/TestAppNonMooseController.pm
+t/lib/TestAppNonMooseController/Controller/Foo.pm
+t/lib/TestAppNonMooseController/ControllerBase.pm
+t/lib/TestAppOnDemand.pm
+t/lib/TestAppOnDemand/Controller/Body.pm
+t/lib/TestAppOneView.pm
+t/lib/TestAppOneView/Controller/Root.pm
+t/lib/TestAppOneView/View/Dummy.pm
+t/lib/TestAppPathBug.pm
+t/lib/TestAppPluginWithConstructor.pm
+t/lib/TestAppPluginWithConstructor/Controller/Root.pm
+t/lib/TestAppShowInternalActions.pm
+t/lib/TestAppShowInternalActions/Controller/Root.pm
+t/lib/TestAppStats.pm
+t/lib/TestAppStats/Controller/Root.pm
+t/lib/TestAppToTestScripts.pm
+t/lib/TestAppUnknownError.pm
+t/lib/TestAppWithMeta.pm
+t/lib/TestAppWithMeta/Controller/Root.pm
+t/lib/TestPluginWithConstructor.pm
 t/optional/mod_perl-locationmatch.pl
 t/optional/mod_perl-non-root.pl
 t/optional/mod_perl.pl
@@ -1,18 +1,27 @@
---- 
-abstract: Catalyst Apache Engines
-author: Sebastian Riedel, <sri@cpan.org>
+---
+abstract: 'Catalyst Apache Engines'
+author:
+  - 'Sebastian Riedel, <sri@cpan.org>'
+build_requires:
+  ExtUtils::MakeMaker: 6.42
+  Test::More: 0.88
+configure_requires:
+  ExtUtils::MakeMaker: 6.42
 distribution_type: module
-generated_by: Module::Install version 0.65
+generated_by: 'Module::Install version 0.99'
 license: perl
-meta-spec: 
-  url: http://module-build.sourceforge.net/META-spec-v1.3.html
-  version: 1.3
+meta-spec:
+  url: http://module-build.sourceforge.net/META-spec-v1.4.html
+  version: 1.4
 name: Catalyst-Engine-Apache
-no_index: 
-  directory: 
+no_index:
+  directory:
     - inc
     - t
-requires: 
-  Catalyst::Runtime: 0
-tests: t/0*.t
-version: 1.12
+requires:
+  Catalyst::Runtime: 5.8
+  Test::More: 0.88
+resources:
+  license: http://dev.perl.org/licenses/
+  repository: http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Engine-Apache/trunk
+version: 1.14
@@ -1,11 +1,25 @@
-use inc::Module::Install 0.65;
+use strict;
+use warnings;
+use inc::Module::Install 0.91;
+use Module::Install::AuthorRequires;
+use Module::Install::AuthorTests;
 
 name 'Catalyst-Engine-Apache';
 all_from 'lib/Catalyst/Engine/Apache.pm';
 
-requires 'Catalyst::Runtime';
+requires 'Catalyst::Runtime' => 5.80;
 
-tests 't/0*.t';
+test_requires 'Test::More' => '0.88';
 
 auto_install;
+resources repository => 'http://dev.catalyst.perl.org/repos/Catalyst/Catalyst-Engine-Apache/trunk';
+
+author_requires 'Test::NoTabs';
+author_tests 't/author';
+
+if ($Module::Install::AUTHOR) {
+    system("pod2text lib/Catalyst/Engine/Apache.pm > README")
+        and die;
+}
+
 WriteAll;
@@ -29,18 +29,42 @@ METHODS
         use Apache2::Const -compile => qw(DECLINED);
         $c->engine->return( Apache2::Const::DECLINED );
 
+  NOTES ABOUT LOCATIONMATCH
+    The Apache engine tries to figure out the correct base path if your app
+    is running within a LocationMatch block. For example:
+
+        <LocationMatch ^/match/(this|that)*>
+            SetHandler          modperl
+            PerlResponseHandler MyApp
+        </LocationMatch>
+
+    This will correctly set the base path to '/match/this/' or
+    '/match/that/' depending on which path was used for the request.
+
+    In some cases this may not be what you want, so you can disable this
+    behavior by adding this to your configuration:
+
+        PerlSetVar CatalystDisableLocationMatch 1
+
+  NOTES ON NON-STANDARD PORTS
+    If you wish to run your site on a non-standard port you will need to use
+    the "Port" Apache config rather than "Listen". This will result in the
+    correct port being added to urls created using "uri_for".
+
+        Port 8080
+
 OVERLOADED METHODS
     This class overloads some methods from "Catalyst::Engine".
 
-    $c->engine->prepare_request($r)
-    $c->engine->prepare_connection
-    $c->engine->prepare_query_parameters
-    $c->engine->prepare_headers
-    $c->engine->prepare_path
-    $c->engine->read_chunk
-    $c->engine->finalize_body
-    $c->engine->finalize_headers
-    $c->engine->write
+    prepare_request($r)
+    prepare_connection
+    prepare_query_parameters
+    prepare_headers
+    prepare_path
+    read_chunk
+    finalize_body
+    finalize_headers
+    write
 
 SEE ALSO
     Catalyst Catalyst::Engine.
@@ -18,7 +18,9 @@ my %FeatureMap = (
 
 # various lexical flags
 my ( @Missing, @Existing,  %DisabledTests, $UnderCPAN,     $HasCPANPLUS );
-my ( $Config,  $CheckOnly, $SkipInstall,   $AcceptDefault, $TestOnly );
+my (
+    $Config, $CheckOnly, $SkipInstall, $AcceptDefault, $TestOnly, $AllDeps
+);
 my ( $PostambleActions, $PostambleUsed );
 
 # See if it's a testing or non-interactive session
@@ -73,6 +75,9 @@ sub _init {
         elsif ( $arg =~ /^--test(?:only)?$/ ) {
             $TestOnly = 1;
         }
+        elsif ( $arg =~ /^--all(?:deps)?$/ ) {
+            $AllDeps = 1;
+        }
     }
 }
 
@@ -115,6 +120,13 @@ sub import {
         )[0]
     );
 
+    # We want to know if we're under CPAN early to avoid prompting, but
+    # if we aren't going to try and install anything anyway then skip the
+    # check entirely since we don't want to have to load (and configure)
+    # an old CPAN just for a cosmetic message
+
+    $UnderCPAN = _check_lock(1) unless $SkipInstall;
+
     while ( my ( $feature, $modules ) = splice( @args, 0, 2 ) ) {
         my ( @required, @tests, @skiptests );
         my $default  = 1;
@@ -163,15 +175,24 @@ sub import {
             }
 
             # XXX: check for conflicts and uninstalls(!) them.
-            if (
-                defined( my $cur = _version_check( _load($mod), $arg ||= 0 ) ) )
+            my $cur = _load($mod);
+            if (_version_cmp ($cur, $arg) >= 0)
             {
                 print "loaded. ($cur" . ( $arg ? " >= $arg" : '' ) . ")\n";
                 push @Existing, $mod => $arg;
                 $DisabledTests{$_} = 1 for map { glob($_) } @skiptests;
             }
             else {
-                print "missing." . ( $arg ? " (would need $arg)" : '' ) . "\n";
+                if (not defined $cur)   # indeed missing
+                {
+                    print "missing." . ( $arg ? " (would need $arg)" : '' ) . "\n";
+                }
+                else
+                {
+                    # no need to check $arg as _version_cmp ($cur, undef) would satisfy >= above
+                    print "too old. ($cur < $arg)\n";
+                }
+
                 push @required, $mod => $arg;
             }
         }
@@ -184,6 +205,8 @@ sub import {
             !$SkipInstall
             and (
                 $CheckOnly
+                or ($mandatory and $UnderCPAN)
+                or $AllDeps
                 or _prompt(
                     qq{==> Auto-install the }
                       . ( @required / 2 )
@@ -214,8 +237,6 @@ sub import {
         }
     }
 
-    $UnderCPAN = _check_lock();    # check for $UnderCPAN
-
     if ( @Missing and not( $CheckOnly or $UnderCPAN ) ) {
         require Config;
         print
@@ -232,23 +253,42 @@ sub import {
     # import to main::
     no strict 'refs';
     *{'main::WriteMakefile'} = \&Write if caller(0) eq 'main';
+
+    return (@Existing, @Missing);
+}
+
+sub _running_under {
+    my $thing = shift;
+    print <<"END_MESSAGE";
+*** Since we're running under ${thing}, I'll just let it take care
+    of the dependency's installation later.
+END_MESSAGE
+    return 1;
 }
 
 # Check to see if we are currently running under CPAN.pm and/or CPANPLUS;
 # if we are, then we simply let it taking care of our dependencies
 sub _check_lock {
-    return unless @Missing;
+    return unless @Missing or @_;
+
+    my $cpan_env = $ENV{PERL5_CPAN_IS_RUNNING};
 
     if ($ENV{PERL5_CPANPLUS_IS_RUNNING}) {
-        print <<'END_MESSAGE';
+        return _running_under($cpan_env ? 'CPAN' : 'CPANPLUS');
+    }
 
-*** Since we're running under CPANPLUS, I'll just let it take care
-    of the dependency's installation later.
-END_MESSAGE
-        return 1;
+    require CPAN;
+
+    if ($CPAN::VERSION > '1.89') {
+        if ($cpan_env) {
+            return _running_under('CPAN');
+        }
+        return; # CPAN.pm new enough, don't need to check further
     }
 
-    _load_cpan();
+    # last ditch attempt, this -will- configure CPAN, very sorry
+
+    _load_cpan(1); # force initialize even though it's already loaded
 
     # Find the CPAN lock-file
     my $lock = MM->catfile( $CPAN::Config->{cpan_home}, ".lock" );
@@ -284,7 +324,7 @@ sub install {
     while ( my ( $pkg, $ver ) = splice( @_, 0, 2 ) ) {
 
         # grep out those already installed
-        if ( defined( _version_check( _load($pkg), $ver ) ) ) {
+        if ( _version_cmp( _load($pkg), $ver ) >= 0 ) {
             push @installed, $pkg;
         }
         else {
@@ -313,7 +353,7 @@ sub install {
         @modules = @newmod;
     }
 
-    if ( _has_cpanplus() ) {
+    if ( _has_cpanplus() and not $ENV{PERL_AUTOINSTALL_PREFER_CPAN} ) {
         _install_cpanplus( \@modules, \@config );
     } else {
         _install_cpan( \@modules, \@config );
@@ -323,7 +363,7 @@ sub install {
 
     # see if we have successfully installed them
     while ( my ( $pkg, $ver ) = splice( @modules, 0, 2 ) ) {
-        if ( defined( _version_check( _load($pkg), $ver ) ) ) {
+        if ( _version_cmp( _load($pkg), $ver ) >= 0 ) {
             push @installed, $pkg;
         }
         elsif ( $args{do_once} and open( FAILED, '>> .#autoinstall.failed' ) ) {
@@ -378,7 +418,7 @@ sub _install_cpanplus {
         my $success;
         my $obj = $modtree->{$pkg};
 
-        if ( $obj and defined( _version_check( $obj->{version}, $ver ) ) ) {
+        if ( $obj and _version_cmp( $obj->{version}, $ver ) >= 0 ) {
             my $pathname = $pkg;
             $pathname =~ s/::/\\W/;
 
@@ -471,7 +511,7 @@ sub _install_cpan {
         my $obj     = CPAN::Shell->expand( Module => $pkg );
         my $success = 0;
 
-        if ( $obj and defined( _version_check( $obj->cpan_version, $ver ) ) ) {
+        if ( $obj and _version_cmp( $obj->cpan_version, $ver ) >= 0 ) {
             my $pathname = $pkg;
             $pathname =~ s/::/\\W/;
 
@@ -535,7 +575,7 @@ sub _update_to {
     my $ver   = shift;
 
     return
-      if defined( _version_check( _load($class), $ver ) );  # no need to upgrade
+      if _version_cmp( _load($class), $ver ) >= 0;  # no need to upgrade
 
     if (
         _prompt( "==> A newer version of $class ($ver) is required. Install?",
@@ -632,9 +672,22 @@ sub _load {
 
 # Load CPAN.pm and it's configuration
 sub _load_cpan {
-    return if $CPAN::VERSION;
+    return if $CPAN::VERSION and $CPAN::Config and not @_;
     require CPAN;
-    if ( $CPAN::HandleConfig::VERSION ) {
+
+    # CPAN-1.82+ adds CPAN::Config::AUTOLOAD to redirect to
+    #    CPAN::HandleConfig->load. CPAN reports that the redirection
+    #    is deprecated in a warning printed at the user.
+
+    # CPAN-1.81 expects CPAN::HandleConfig->load, does not have
+    #   $CPAN::HandleConfig::VERSION but cannot handle
+    #   CPAN::Config->load
+
+    # Which "versions expect CPAN::Config->load?
+
+    if ( $CPAN::HandleConfig::VERSION
+        || CPAN::HandleConfig->can('load')
+    ) {
         # Newer versions of CPAN have a HandleConfig module
         CPAN::HandleConfig->load;
     } else {
@@ -644,9 +697,11 @@ sub _load_cpan {
 }
 
 # compare two versions, either use Sort::Versions or plain comparison
-sub _version_check {
+# return values same as <=>
+sub _version_cmp {
     my ( $cur, $min ) = @_;
-    return unless defined $cur;
+    return -1 unless defined $cur;  # if 0 keep comparing
+    return 1 unless $min;
 
     $cur =~ s/\s+$//;
 
@@ -657,16 +712,13 @@ sub _version_check {
             ) {
 
             # use version.pm if it is installed.
-            return (
-                ( version->new($cur) >= version->new($min) ) ? $cur : undef );
+            return version->new($cur) <=> version->new($min);
         }
         elsif ( $Sort::Versions::VERSION or defined( _load('Sort::Versions') ) )
         {
 
             # use Sort::Versions as the sorting algorithm for a.b.c versions
-            return ( ( Sort::Versions::versioncmp( $cur, $min ) != -1 )
-                ? $cur
-                : undef );
+            return Sort::Versions::versioncmp( $cur, $min );
         }
 
         warn "Cannot reliably compare non-decimal formatted versions.\n"
@@ -675,7 +727,7 @@ sub _version_check {
 
     # plain comparison
     local $^W = 0;    # shuts off 'not numeric' bugs
-    return ( $cur >= $min ? $cur : undef );
+    return $cur <=> $min;
 }
 
 # nothing; this usage is deprecated.
@@ -706,7 +758,7 @@ sub _make_args {
       if $Config;
 
     $PostambleActions = (
-        $missing
+        ($missing and not $UnderCPAN)
         ? "\$(PERL) $0 --config=$config --installdeps=$missing"
         : "\$(NOECHO) \$(NOOP)"
     );
@@ -746,7 +798,7 @@ sub Write {
 sub postamble {
     $PostambleUsed = 1;
 
-    return << ".";
+    return <<"END_MAKE";
 
 config :: installdeps
 \t\$(NOECHO) \$(NOOP)
@@ -757,7 +809,7 @@ checkdeps ::
 installdeps ::
 \t$PostambleActions
 
-.
+END_MAKE
 
 }
 
@@ -765,4 +817,4 @@ installdeps ::
 
 __END__
 
-#line 1003
+#line 1071
@@ -0,0 +1,38 @@
+#line 1
+use strict;
+use warnings;
+
+package Module::Install::AuthorRequires;
+
+use base 'Module::Install::Base';
+
+# cargo cult
+BEGIN {
+    our $VERSION = '0.02';
+    our $ISCORE  = 1;
+}
+
+sub author_requires {
+    my $self = shift;
+
+    return $self->{values}->{author_requires}
+        unless @_;
+
+    my @added;
+    while (@_) {
+        my $mod = shift or last;
+        my $version = shift || 0;
+        push @added, [$mod => $version];
+    }
+
+    push @{ $self->{values}->{author_requires} }, @added;
+    $self->admin->author_requires(@added);
+
+    return map { @$_ } @added;
+}
+
+1;
+
+__END__
+
+#line 92
@@ -0,0 +1,59 @@
+#line 1
+package Module::Install::AuthorTests;
+
+use 5.005;
+use strict;
+use Module::Install::Base;
+use Carp ();
+
+#line 16
+
+use vars qw{$VERSION $ISCORE @ISA};
+BEGIN {
+  $VERSION = '0.002';
+  $ISCORE  = 1;
+  @ISA     = qw{Module::Install::Base};
+}
+
+#line 42
+
+sub author_tests {
+  my ($self, @dirs) = @_;
+  _add_author_tests($self, \@dirs, 0);
+}
+
+#line 56
+
+sub recursive_author_tests {
+  my ($self, @dirs) = @_;
+  _add_author_tests($self, \@dirs, 1);
+}
+
+sub _wanted {
+  my $href = shift;
+  sub { /\.t$/ and -f $_ and $href->{$File::Find::dir} = 1 }
+}
+
+sub _add_author_tests {
+  my ($self, $dirs, $recurse) = @_;
+  return unless $Module::Install::AUTHOR;
+
+  my @tests = $self->tests ? (split / /, $self->tests) : 't/*.t';
+
+  # XXX: pick a default, later -- rjbs, 2008-02-24
+  my @dirs = @$dirs ? @$dirs : Carp::confess "no dirs given to author_tests";
+     @dirs = grep { -d } @dirs;
+
+  if ($recurse) {
+    require File::Find;
+    my %test_dir;
+    File::Find::find(_wanted(\%test_dir), @dirs);
+    $self->tests( join ' ', @tests, map { "$_/*.t" } sort keys %test_dir );
+  } else {
+    $self->tests( join ' ', @tests, map { "$_/*.t" } sort @dirs );
+  }
+}
+
+#line 107
+
+1;
@@ -2,13 +2,13 @@
 package Module::Install::AutoInstall;
 
 use strict;
-use Module::Install::Base;
+use Module::Install::Base ();
 
-use vars qw{$VERSION $ISCORE @ISA};
+use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.65';
+	$VERSION = '0.99';
+	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
 }
 
 sub AutoInstall { $_[0] }
@@ -37,12 +37,25 @@ sub auto_install {
     $self->include('Module::AutoInstall');
     require Module::AutoInstall;
 
-    Module::AutoInstall->import(
+    my @features_require = Module::AutoInstall->import(
         (@config ? (-config => \@config) : ()),
         (@core   ? (-core   => \@core)   : ()),
         $self->features,
     );
 
+    my %seen;
+    my @requires = map @$_, map @$_, grep ref, $self->requires;
+    while (my ($mod, $ver) = splice(@requires, 0, 2)) {
+        $seen{$mod}{$ver}++;
+    }
+
+    my @deduped;
+    while (my ($mod, $ver) = splice(@features_require, 0, 2)) {
+        push @deduped, $mod => $ver unless $seen{$mod}{$ver}++;
+    }
+
+    $self->requires(@deduped);
+
     $self->makemaker_args( Module::AutoInstall::_make_args() );
 
     my $class = ref($self);
@@ -1,7 +1,11 @@
 #line 1
 package Module::Install::Base;
 
-$VERSION = '0.65';
+use strict 'vars';
+use vars qw{$VERSION};
+BEGIN {
+	$VERSION = '0.99';
+}
 
 # Suspend handler for "redefined" warnings
 BEGIN {
@@ -9,52 +13,61 @@ BEGIN {
 	$SIG{__WARN__} = sub { $w };
 }
 
-### This is the ONLY module that shouldn't have strict on
-# use strict;
-
-#line 41
+#line 42
 
 sub new {
-    my ($class, %args) = @_;
-
-    foreach my $method ( qw(call load) ) {
-        *{"$class\::$method"} = sub {
-            shift()->_top->$method(@_);
-        } unless defined &{"$class\::$method"};
-    }
-
-    bless( \%args, $class );
+	my $class = shift;
+	unless ( defined &{"${class}::call"} ) {
+		*{"${class}::call"} = sub { shift->_top->call(@_) };
+	}
+	unless ( defined &{"${class}::load"} ) {
+		*{"${class}::load"} = sub { shift->_top->load(@_) };
+	}
+	bless { @_ }, $class;
 }
 
 #line 61
 
 sub AUTOLOAD {
-    my $self = shift;
-    local $@;
-    my $autoload = eval { $self->_top->autoload } or return;
-    goto &$autoload;
+	local $@;
+	my $func = eval { shift->_top->autoload } or return;
+	goto &$func;
 }
 
-#line 76
+#line 75
 
-sub _top { $_[0]->{_top} }
+sub _top {
+	$_[0]->{_top};
+}
 
-#line 89
+#line 90
 
 sub admin {
-    $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new;
+	$_[0]->_top->{admin}
+	or
+	Module::Install::Base::FakeAdmin->new;
 }
 
+#line 106
+
 sub is_admin {
-    $_[0]->admin->VERSION;
+	! $_[0]->admin->isa('Module::Install::Base::FakeAdmin');
 }
 
 sub DESTROY {}
 
 package Module::Install::Base::FakeAdmin;
 
-my $Fake;
-sub new { $Fake ||= bless(\@_, $_[0]) }
+use vars qw{$VERSION};
+BEGIN {
+	$VERSION = $Module::Install::Base::VERSION;
+}
+
+my $fake;
+
+sub new {
+	$fake ||= bless(\@_, $_[0]);
+}
 
 sub AUTOLOAD {}
 
@@ -67,4 +80,4 @@ BEGIN {
 
 1;
 
-#line 138
+#line 159
@@ -2,18 +2,16 @@
 package Module::Install::Can;
 
 use strict;
-use Module::Install::Base;
-use Config ();
-### This adds a 5.005 Perl version dependency.
-### This is a bug and will be fixed.
-use File::Spec ();
-use ExtUtils::MakeMaker ();
-
-use vars qw{$VERSION $ISCORE @ISA};
+use Config                ();
+use File::Spec            ();
+use ExtUtils::MakeMaker   ();
+use Module::Install::Base ();
+
+use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.65';
+	$VERSION = '0.99';
+	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
 }
 
 # check if we can load some module
@@ -39,6 +37,7 @@ sub can_run {
 	return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd));
 
 	for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') {
+		next if $dir eq '';
 		my $abs = File::Spec->catfile($dir, $_[1]);
 		return $abs if (-x $abs or $abs = MM->maybe_command($abs));
 	}
@@ -79,4 +78,4 @@ if ( $^O eq 'cygwin' ) {
 
 __END__
 
-#line 157
+#line 156
@@ -2,24 +2,24 @@
 package Module::Install::Fetch;
 
 use strict;
-use Module::Install::Base;
+use Module::Install::Base ();
 
-use vars qw{$VERSION $ISCORE @ISA};
+use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.65';
+	$VERSION = '0.99';
+	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
 }
 
 sub get_file {
     my ($self, %args) = @_;
-    my ($scheme, $host, $path, $file) = 
+    my ($scheme, $host, $path, $file) =
         $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
 
     if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) {
         $args{url} = $args{ftp_url}
             or (warn("LWP support unavailable!\n"), return);
-        ($scheme, $host, $path, $file) = 
+        ($scheme, $host, $path, $file) =
             $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
     }
 
@@ -2,13 +2,13 @@
 package Module::Install::Include;
 
 use strict;
-use Module::Install::Base;
+use Module::Install::Base ();
 
-use vars qw{$VERSION $ISCORE @ISA};
+use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.65';
+	$VERSION = '0.99';
+	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
 }
 
 sub include {
@@ -2,14 +2,15 @@
 package Module::Install::Makefile;
 
 use strict 'vars';
-use Module::Install::Base;
-use ExtUtils::MakeMaker ();
+use ExtUtils::MakeMaker   ();
+use Module::Install::Base ();
+use Fcntl qw/:flock :seek/;
 
-use vars qw{$VERSION $ISCORE @ISA};
+use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.65';
+	$VERSION = '0.99';
+	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
 }
 
 sub Makefile { $_[0] }
@@ -17,196 +18,398 @@ sub Makefile { $_[0] }
 my %seen = ();
 
 sub prompt {
-    shift;
+	shift;
+
+	# Infinite loop protection
+	my @c = caller();
+	if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) {
+		die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])";
+	}
+
+	# In automated testing or non-interactive session, always use defaults
+	if ( ($ENV{AUTOMATED_TESTING} or -! -t STDIN) and ! $ENV{PERL_MM_USE_DEFAULT} ) {
+		local $ENV{PERL_MM_USE_DEFAULT} = 1;
+		goto &ExtUtils::MakeMaker::prompt;
+	} else {
+		goto &ExtUtils::MakeMaker::prompt;
+	}
+}
 
-    # Infinite loop protection
-    my @c = caller();
-    if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) {
-        die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])";
-    }
+# Store a cleaned up version of the MakeMaker version,
+# since we need to behave differently in a variety of
+# ways based on the MM version.
+my $makemaker = eval $ExtUtils::MakeMaker::VERSION;
 
-    # In automated testing, always use defaults
-    if ( $ENV{AUTOMATED_TESTING} and ! $ENV{PERL_MM_USE_DEFAULT} ) {
-        local $ENV{PERL_MM_USE_DEFAULT} = 1;
-        goto &ExtUtils::MakeMaker::prompt;
-    } else {
-        goto &ExtUtils::MakeMaker::prompt;
-    }
+# If we are passed a param, do a "newer than" comparison.
+# Otherwise, just return the MakeMaker version.
+sub makemaker {
+	( @_ < 2 or $makemaker >= eval($_[1]) ) ? $makemaker : 0
 }
 
+# Ripped from ExtUtils::MakeMaker 6.56, and slightly modified
+# as we only need to know here whether the attribute is an array
+# or a hash or something else (which may or may not be appendable).
+my %makemaker_argtype = (
+ C                  => 'ARRAY',
+ CONFIG             => 'ARRAY',
+# CONFIGURE          => 'CODE', # ignore
+ DIR                => 'ARRAY',
+ DL_FUNCS           => 'HASH',
+ DL_VARS            => 'ARRAY',
+ EXCLUDE_EXT        => 'ARRAY',
+ EXE_FILES          => 'ARRAY',
+ FUNCLIST           => 'ARRAY',
+ H                  => 'ARRAY',
+ IMPORTS            => 'HASH',
+ INCLUDE_EXT        => 'ARRAY',
+ LIBS               => 'ARRAY', # ignore ''
+ MAN1PODS           => 'HASH',
+ MAN3PODS           => 'HASH',
+ META_ADD           => 'HASH',
+ META_MERGE         => 'HASH',
+ PL_FILES           => 'HASH',
+ PM                 => 'HASH',
+ PMLIBDIRS          => 'ARRAY',
+ PMLIBPARENTDIRS    => 'ARRAY',
+ PREREQ_PM          => 'HASH',
+ CONFIGURE_REQUIRES => 'HASH',
+ SKIP               => 'ARRAY',
+ TYPEMAPS           => 'ARRAY',
+ XS                 => 'HASH',
+# VERSION            => ['version',''],  # ignore
+# _KEEP_AFTER_FLUSH  => '',
+
+ clean      => 'HASH',
+ depend     => 'HASH',
+ dist       => 'HASH',
+ dynamic_lib=> 'HASH',
+ linkext    => 'HASH',
+ macro      => 'HASH',
+ postamble  => 'HASH',
+ realclean  => 'HASH',
+ test       => 'HASH',
+ tool_autosplit => 'HASH',
+
+ # special cases where you can use makemaker_append
+ CCFLAGS   => 'APPENDABLE',
+ DEFINE    => 'APPENDABLE',
+ INC       => 'APPENDABLE',
+ LDDLFLAGS => 'APPENDABLE',
+ LDFROM    => 'APPENDABLE',
+);
+
 sub makemaker_args {
-    my $self = shift;
-    my $args = ($self->{makemaker_args} ||= {});
-    %$args = ( %$args, @_ ) if @_;
-    $args;
+	my ($self, %new_args) = @_;
+	my $args = ( $self->{makemaker_args} ||= {} );
+	foreach my $key (keys %new_args) {
+		if ($makemaker_argtype{$key}) {
+			if ($makemaker_argtype{$key} eq 'ARRAY') {
+				$args->{$key} = [] unless defined $args->{$key};
+				unless (ref $args->{$key} eq 'ARRAY') {
+					$args->{$key} = [$args->{$key}]
+				}
+				push @{$args->{$key}},
+					ref $new_args{$key} eq 'ARRAY'
+						? @{$new_args{$key}}
+						: $new_args{$key};
+			}
+			elsif ($makemaker_argtype{$key} eq 'HASH') {
+				$args->{$key} = {} unless defined $args->{$key};
+				foreach my $skey (keys %{ $new_args{$key} }) {
+					$args->{$key}{$skey} = $new_args{$key}{$skey};
+				}
+			}
+			elsif ($makemaker_argtype{$key} eq 'APPENDABLE') {
+				$self->makemaker_append($key => $new_args{$key});
+			}
+		}
+		else {
+			if (defined $args->{$key}) {
+				warn qq{MakeMaker attribute "$key" is overriden; use "makemaker_append" to append values\n};
+			}
+			$args->{$key} = $new_args{$key};
+		}
+	}
+	return $args;
 }
 
 # For mm args that take multiple space-seperated args,
 # append an argument to the current list.
 sub makemaker_append {
-    my $self = shift;
-    my $name = shift;
-    my $args = $self->makemaker_args;
-    $args->{name} = defined $args->{$name}
-    	? join( ' ', $args->{name}, @_ )
-    	: join( ' ', @_ );
+	my $self = shift;
+	my $name = shift;
+	my $args = $self->makemaker_args;
+	$args->{$name} = defined $args->{$name}
+		? join( ' ', $args->{$name}, @_ )
+		: join( ' ', @_ );
 }
 
 sub build_subdirs {
-    my $self    = shift;
-    my $subdirs = $self->makemaker_args->{DIR} ||= [];
-    for my $subdir (@_) {
-        push @$subdirs, $subdir;
-    }
+	my $self    = shift;
+	my $subdirs = $self->makemaker_args->{DIR} ||= [];
+	for my $subdir (@_) {
+		push @$subdirs, $subdir;
+	}
 }
 
 sub clean_files {
-    my $self  = shift;
-    my $clean = $self->makemaker_args->{clean} ||= {};
-    %$clean = (
-        %$clean, 
-        FILES => join(' ', grep length, $clean->{FILES}, @_),
-    );
+	my $self  = shift;
+	my $clean = $self->makemaker_args->{clean} ||= {};
+	  %$clean = (
+		%$clean,
+		FILES => join ' ', grep { length $_ } ($clean->{FILES} || (), @_),
+	);
 }
 
 sub realclean_files {
-    my $self  = shift;
-    my $realclean = $self->makemaker_args->{realclean} ||= {};
-    %$realclean = (
-        %$realclean, 
-        FILES => join(' ', grep length, $realclean->{FILES}, @_),
-    );
+	my $self      = shift;
+	my $realclean = $self->makemaker_args->{realclean} ||= {};
+	  %$realclean = (
+		%$realclean,
+		FILES => join ' ', grep { length $_ } ($realclean->{FILES} || (), @_),
+	);
 }
 
 sub libs {
-    my $self = shift;
-    my $libs = ref $_[0] ? shift : [ shift ];
-    $self->makemaker_args( LIBS => $libs );
+	my $self = shift;
+	my $libs = ref $_[0] ? shift : [ shift ];
+	$self->makemaker_args( LIBS => $libs );
 }
 
 sub inc {
-    my $self = shift;
-    $self->makemaker_args( INC => shift );
+	my $self = shift;
+	$self->makemaker_args( INC => shift );
 }
 
-sub write {
-    my $self = shift;
-    die "&Makefile->write() takes no arguments\n" if @_;
-
-    my $args = $self->makemaker_args;
-    $args->{DISTNAME} = $self->name;
-    $args->{NAME}     = $self->module_name || $self->name || $self->determine_NAME($args);
-    $args->{VERSION}  = $self->version || $self->determine_VERSION($args);
-    $args->{NAME}     =~ s/-/::/g;
-    if ( $self->tests ) {
-        $args->{test} = { TESTS => $self->tests };
-    }
-    if ($] >= 5.005) {
-        $args->{ABSTRACT} = $self->abstract;
-        $args->{AUTHOR}   = $self->author;
-    }
-    if ( eval($ExtUtils::MakeMaker::VERSION) >= 6.10 ) {
-        $args->{NO_META} = 1;
-    }
-    if ( eval($ExtUtils::MakeMaker::VERSION) > 6.17 and $self->sign ) {
-        $args->{SIGN} = 1;
-    }
-    unless ( $self->is_admin ) {
-        delete $args->{SIGN};
-    }
-
-    # merge both kinds of requires into prereq_pm
-    my $prereq = ($args->{PREREQ_PM} ||= {});
-    %$prereq = ( %$prereq, map { @$_ } map { @$_ } grep $_,
-                 ($self->build_requires, $self->requires) );
-
-    # merge both kinds of requires into prereq_pm
-    my $subdirs = ($args->{DIR} ||= []);
-    if ($self->bundles) {
-        foreach my $bundle (@{ $self->bundles }) {
-            my ($file, $dir) = @$bundle;
-            push @$subdirs, $dir if -d $dir;
-            delete $prereq->{$file};
-        }
-    }
-
-    if ( my $perl_version = $self->perl_version ) {
-        eval "use $perl_version; 1"
-            or die "ERROR: perl: Version $] is installed, "
-                . "but we need version >= $perl_version";
-    }
-
-    $args->{INSTALLDIRS} = $self->installdirs;
-
-    my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_})} keys %$args;
-
-    my $user_preop = delete $args{dist}->{PREOP};
-    if (my $preop = $self->admin->preop($user_preop)) {
-        $args{dist} = $preop;
-    }
-
-    my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);
-    $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile');
+sub _wanted_t {
 }
 
-sub fix_up_makefile {
-    my $self          = shift;
-    my $makefile_name = shift;
-    my $top_class     = ref($self->_top) || '';
-    my $top_version   = $self->_top->VERSION || '';
-
-    my $preamble = $self->preamble 
-        ? "# Preamble by $top_class $top_version\n"
-            . $self->preamble
-        : '';
-    my $postamble = "# Postamble by $top_class $top_version\n"
-        . ($self->postamble || '');
-
-    local *MAKEFILE;
-    open MAKEFILE, "< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
-    my $makefile = do { local $/; <MAKEFILE> };
-    close MAKEFILE or die $!;
-
-    $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /;
-    $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g;
-    $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g;
-    $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m;
-    $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m;
-
-    # Module::Install will never be used to build the Core Perl
-    # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks
-    # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist
-    $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m;
-    #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m;
-
-    # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well.
-    $makefile =~ s/("?)-I\$\(PERL_LIB\)\1//g;
-
-    # XXX - This is currently unused; not sure if it breaks other MM-users
-    # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg;
+sub tests_recursive {
+	my $self = shift;
+	my $dir = shift || 't';
+	unless ( -d $dir ) {
+		die "tests_recursive dir '$dir' does not exist";
+	}
+	my %tests = map { $_ => 1 } split / /, ($self->tests || '');
+	require File::Find;
+	File::Find::find(
+        sub { /\.t$/ and -f $_ and $tests{"$File::Find::dir/*.t"} = 1 },
+        $dir
+    );
+	$self->tests( join ' ', sort keys %tests );
+}
 
-    open  MAKEFILE, "> $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
-    print MAKEFILE  "$preamble$makefile$postamble" or die $!;
-    close MAKEFILE  or die $!;
+sub write {
+	my $self = shift;
+	die "&Makefile->write() takes no arguments\n" if @_;
+
+	# Check the current Perl version
+	my $perl_version = $self->perl_version;
+	if ( $perl_version ) {
+		eval "use $perl_version; 1"
+			or die "ERROR: perl: Version $] is installed, "
+			. "but we need version >= $perl_version";
+	}
+
+	# Make sure we have a new enough MakeMaker
+	require ExtUtils::MakeMaker;
+
+	if ( $perl_version and $self->_cmp($perl_version, '5.006') >= 0 ) {
+		# MakeMaker can complain about module versions that include
+		# an underscore, even though its own version may contain one!
+		# Hence the funny regexp to get rid of it.  See RT #35800
+		# for details.
+		my $v = $ExtUtils::MakeMaker::VERSION =~ /^(\d+\.\d+)/;
+		$self->build_requires(     'ExtUtils::MakeMaker' => $v );
+		$self->configure_requires( 'ExtUtils::MakeMaker' => $v );
+	} else {
+		# Allow legacy-compatibility with 5.005 by depending on the
+		# most recent EU:MM that supported 5.005.
+		$self->build_requires(     'ExtUtils::MakeMaker' => 6.42 );
+		$self->configure_requires( 'ExtUtils::MakeMaker' => 6.42 );
+	}
+
+	# Generate the MakeMaker params
+	my $args = $self->makemaker_args;
+	$args->{DISTNAME} = $self->name;
+	$args->{NAME}     = $self->module_name || $self->name;
+	$args->{NAME}     =~ s/-/::/g;
+	$args->{VERSION}  = $self->version or die <<'EOT';
+ERROR: Can't determine distribution version. Please specify it
+explicitly via 'version' in Makefile.PL, or set a valid $VERSION
+in a module, and provide its file path via 'version_from' (or
+'all_from' if you prefer) in Makefile.PL.
+EOT
+
+	$DB::single = 1;
+	if ( $self->tests ) {
+		my @tests = split ' ', $self->tests;
+		my %seen;
+		$args->{test} = {
+			TESTS => (join ' ', grep {!$seen{$_}++} @tests),
+		};
+    } elsif ( $Module::Install::ExtraTests::use_extratests ) {
+        # Module::Install::ExtraTests doesn't set $self->tests and does its own tests via harness.
+        # So, just ignore our xt tests here.
+	} elsif ( -d 'xt' and ($Module::Install::AUTHOR or $ENV{RELEASE_TESTING}) ) {
+		$args->{test} = {
+			TESTS => join( ' ', map { "$_/*.t" } grep { -d $_ } qw{ t xt } ),
+		};
+	}
+	if ( $] >= 5.005 ) {
+		$args->{ABSTRACT} = $self->abstract;
+		$args->{AUTHOR}   = join ', ', @{$self->author || []};
+	}
+	if ( $self->makemaker(6.10) ) {
+		$args->{NO_META}   = 1;
+		#$args->{NO_MYMETA} = 1;
+	}
+	if ( $self->makemaker(6.17) and $self->sign ) {
+		$args->{SIGN} = 1;
+	}
+	unless ( $self->is_admin ) {
+		delete $args->{SIGN};
+	}
+	if ( $self->makemaker(6.31) and $self->license ) {
+		$args->{LICENSE} = $self->license;
+	}
+
+	my $prereq = ($args->{PREREQ_PM} ||= {});
+	%$prereq = ( %$prereq,
+		map { @$_ } # flatten [module => version]
+		map { @$_ }
+		grep $_,
+		($self->requires)
+	);
+
+	# Remove any reference to perl, PREREQ_PM doesn't support it
+	delete $args->{PREREQ_PM}->{perl};
+
+	# Merge both kinds of requires into BUILD_REQUIRES
+	my $build_prereq = ($args->{BUILD_REQUIRES} ||= {});
+	%$build_prereq = ( %$build_prereq,
+		map { @$_ } # flatten [module => version]
+		map { @$_ }
+		grep $_,
+		($self->configure_requires, $self->build_requires)
+	);
+
+	# Remove any reference to perl, BUILD_REQUIRES doesn't support it
+	delete $args->{BUILD_REQUIRES}->{perl};
+
+	# Delete bundled dists from prereq_pm, add it to Makefile DIR
+	my $subdirs = ($args->{DIR} || []);
+	if ($self->bundles) {
+		my %processed;
+		foreach my $bundle (@{ $self->bundles }) {
+			my ($mod_name, $dist_dir) = @$bundle;
+			delete $prereq->{$mod_name};
+			$dist_dir = File::Basename::basename($dist_dir); # dir for building this module
+			if (not exists $processed{$dist_dir}) {
+				if (-d $dist_dir) {
+					# List as sub-directory to be processed by make
+					push @$subdirs, $dist_dir;
+				}
+				# Else do nothing: the module is already present on the system
+				$processed{$dist_dir} = undef;
+			}
+		}
+	}
+
+	unless ( $self->makemaker('6.55_03') ) {
+		%$prereq = (%$prereq,%$build_prereq);
+		delete $args->{BUILD_REQUIRES};
+	}
+
+	if ( my $perl_version = $self->perl_version ) {
+		eval "use $perl_version; 1"
+			or die "ERROR: perl: Version $] is installed, "
+			. "but we need version >= $perl_version";
+
+		if ( $self->makemaker(6.48) ) {
+			$args->{MIN_PERL_VERSION} = $perl_version;
+		}
+	}
+
+	if ($self->installdirs) {
+		warn qq{old INSTALLDIRS (probably set by makemaker_args) is overriden by installdirs\n} if $args->{INSTALLDIRS};
+		$args->{INSTALLDIRS} = $self->installdirs;
+	}
+
+	my %args = map {
+		( $_ => $args->{$_} ) } grep {defined($args->{$_} )
+	} keys %$args;
+
+	my $user_preop = delete $args{dist}->{PREOP};
+	if ( my $preop = $self->admin->preop($user_preop) ) {
+		foreach my $key ( keys %$preop ) {
+			$args{dist}->{$key} = $preop->{$key};
+		}
+	}
+
+	my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);
+	$self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile');
+}
 
-    1;
+sub fix_up_makefile {
+	my $self          = shift;
+	my $makefile_name = shift;
+	my $top_class     = ref($self->_top) || '';
+	my $top_version   = $self->_top->VERSION || '';
+
+	my $preamble = $self->preamble
+		? "# Preamble by $top_class $top_version\n"
+			. $self->preamble
+		: '';
+	my $postamble = "# Postamble by $top_class $top_version\n"
+		. ($self->postamble || '');
+
+	local *MAKEFILE;
+	open MAKEFILE, "+< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
+	eval { flock MAKEFILE, LOCK_EX };
+	my $makefile = do { local $/; <MAKEFILE> };
+
+	$makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /;
+	$makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g;
+	$makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g;
+	$makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m;
+	$makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m;
+
+	# Module::Install will never be used to build the Core Perl
+	# Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks
+	# PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist
+	$makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m;
+	#$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m;
+
+	# Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well.
+	$makefile =~ s/(\"?)-I\$\(PERL_LIB\)\1//g;
+
+	# XXX - This is currently unused; not sure if it breaks other MM-users
+	# $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg;
+
+	seek MAKEFILE, 0, SEEK_SET;
+	truncate MAKEFILE, 0;
+	print MAKEFILE  "$preamble$makefile$postamble" or die $!;
+	close MAKEFILE  or die $!;
+
+	1;
 }
 
 sub preamble {
-    my ($self, $text) = @_;
-    $self->{preamble} = $text . $self->{preamble} if defined $text;
-    $self->{preamble};
+	my ($self, $text) = @_;
+	$self->{preamble} = $text . $self->{preamble} if defined $text;
+	$self->{preamble};
 }
 
 sub postamble {
-    my ($self, $text) = @_;
-    $self->{postamble} ||= $self->admin->postamble;
-    $self->{postamble} .= $text if defined $text;
-    $self->{postamble}
+	my ($self, $text) = @_;
+	$self->{postamble} ||= $self->admin->postamble;
+	$self->{postamble} .= $text if defined $text;
+	$self->{postamble}
 }
 
 1;
 
 __END__
 
-#line 338
+#line 541
@@ -2,322 +2,714 @@
 package Module::Install::Metadata;
 
 use strict 'vars';
-use Module::Install::Base;
+use Module::Install::Base ();
 
-use vars qw{$VERSION $ISCORE @ISA};
+use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.65';
+	$VERSION = '0.99';
+	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
 }
 
+my @boolean_keys = qw{
+	sign
+};
+
 my @scalar_keys = qw{
-    name module_name abstract author version license
-    distribution_type perl_version tests installdirs
+	name
+	module_name
+	abstract
+	version
+	distribution_type
+	tests
+	installdirs
 };
 
 my @tuple_keys = qw{
-    build_requires requires recommends bundles
+	configure_requires
+	build_requires
+	requires
+	recommends
+	bundles
+	resources
 };
 
-sub Meta            { shift        }
-sub Meta_ScalarKeys { @scalar_keys }
-sub Meta_TupleKeys  { @tuple_keys  }
-
-foreach my $key (@scalar_keys) {
-    *$key = sub {
-        my $self = shift;
-        return $self->{values}{$key} if defined wantarray and !@_;
-        $self->{values}{$key} = shift;
-        return $self;
-    };
-}
-
-foreach my $key (@tuple_keys) {
-    *$key = sub {
-        my $self = shift;
-        return $self->{values}{$key} unless @_;
-
-        my @rv;
-        while (@_) {
-            my $module = shift or last;
-            my $version = shift || 0;
-            if ( $module eq 'perl' ) {
-                $version =~ s{^(\d+)\.(\d+)\.(\d+)}
-                             {$1 + $2/1_000 + $3/1_000_000}e;
-                $self->perl_version($version);
-                next;
-            }
-            my $rv = [ $module, $version ];
-            push @rv, $rv;
-        }
-        push @{ $self->{values}{$key} }, @rv;
-        @rv;
-    };
+my @resource_keys = qw{
+	homepage
+	bugtracker
+	repository
+};
+
+my @array_keys = qw{
+	keywords
+	author
+};
+
+*authors = \&author;
+
+sub Meta              { shift          }
+sub Meta_BooleanKeys  { @boolean_keys  }
+sub Meta_ScalarKeys   { @scalar_keys   }
+sub Meta_TupleKeys    { @tuple_keys    }
+sub Meta_ResourceKeys { @resource_keys }
+sub Meta_ArrayKeys    { @array_keys    }
+
+foreach my $key ( @boolean_keys ) {
+	*$key = sub {
+		my $self = shift;
+		if ( defined wantarray and not @_ ) {
+			return $self->{values}->{$key};
+		}
+		$self->{values}->{$key} = ( @_ ? $_[0] : 1 );
+		return $self;
+	};
+}
+
+foreach my $key ( @scalar_keys ) {
+	*$key = sub {
+		my $self = shift;
+		return $self->{values}->{$key} if defined wantarray and !@_;
+		$self->{values}->{$key} = shift;
+		return $self;
+	};
 }
 
+foreach my $key ( @array_keys ) {
+	*$key = sub {
+		my $self = shift;
+		return $self->{values}->{$key} if defined wantarray and !@_;
+		$self->{values}->{$key} ||= [];
+		push @{$self->{values}->{$key}}, @_;
+		return $self;
+	};
+}
+
+foreach my $key ( @resource_keys ) {
+	*$key = sub {
+		my $self = shift;
+		unless ( @_ ) {
+			return () unless $self->{values}->{resources};
+			return map  { $_->[1] }
+			       grep { $_->[0] eq $key }
+			       @{ $self->{values}->{resources} };
+		}
+		return $self->{values}->{resources}->{$key} unless @_;
+		my $uri = shift or die(
+			"Did not provide a value to $key()"
+		);
+		$self->resources( $key => $uri );
+		return 1;
+	};
+}
+
+foreach my $key ( grep { $_ ne "resources" } @tuple_keys) {
+	*$key = sub {
+		my $self = shift;
+		return $self->{values}->{$key} unless @_;
+		my @added;
+		while ( @_ ) {
+			my $module  = shift or last;
+			my $version = shift || 0;
+			push @added, [ $module, $version ];
+		}
+		push @{ $self->{values}->{$key} }, @added;
+		return map {@$_} @added;
+	};
+}
+
+# Resource handling
+my %lc_resource = map { $_ => 1 } qw{
+	homepage
+	license
+	bugtracker
+	repository
+};
+
+sub resources {
+	my $self = shift;
+	while ( @_ ) {
+		my $name  = shift or last;
+		my $value = shift or next;
+		if ( $name eq lc $name and ! $lc_resource{$name} ) {
+			die("Unsupported reserved lowercase resource '$name'");
+		}
+		$self->{values}->{resources} ||= [];
+		push @{ $self->{values}->{resources} }, [ $name, $value ];
+	}
+	$self->{values}->{resources};
+}
+
+# Aliases for build_requires that will have alternative
+# meanings in some future version of META.yml.
+sub test_requires     { shift->build_requires(@_) }
+sub install_requires  { shift->build_requires(@_) }
+
+# Aliases for installdirs options
 sub install_as_core   { $_[0]->installdirs('perl')   }
 sub install_as_cpan   { $_[0]->installdirs('site')   }
 sub install_as_site   { $_[0]->installdirs('site')   }
 sub install_as_vendor { $_[0]->installdirs('vendor') }
 
-sub sign {
-    my $self = shift;
-    return $self->{'values'}{'sign'} if defined wantarray and !@_;
-    $self->{'values'}{'sign'} = ( @_ ? $_[0] : 1 );
-    return $self;
-}
-
 sub dynamic_config {
 	my $self = shift;
 	unless ( @_ ) {
-		warn "You MUST provide an explicit true/false value to dynamic_config, skipping\n";
+		warn "You MUST provide an explicit true/false value to dynamic_config\n";
 		return $self;
 	}
-	$self->{'values'}{'dynamic_config'} = $_[0] ? 1 : 0;
-	return $self;
+	$self->{values}->{dynamic_config} = $_[0] ? 1 : 0;
+	return 1;
 }
 
-sub all_from {
-    my ( $self, $file ) = @_;
-
-    unless ( defined($file) ) {
-        my $name = $self->name
-            or die "all_from called with no args without setting name() first";
-        $file = join('/', 'lib', split(/-/, $name)) . '.pm';
-        $file =~ s{.*/}{} unless -e $file;
-        die "all_from: cannot find $file from $name" unless -e $file;
-    }
+sub perl_version {
+	my $self = shift;
+	return $self->{values}->{perl_version} unless @_;
+	my $version = shift or die(
+		"Did not provide a value to perl_version()"
+	);
 
-    $self->version_from($file)      unless $self->version;
-    $self->perl_version_from($file) unless $self->perl_version;
+	# Normalize the version
+	$version = $self->_perl_version($version);
 
-    # The remaining probes read from POD sections; if the file
-    # has an accompanying .pod, use that instead
-    my $pod = $file;
-    if ( $pod =~ s/\.pm$/.pod/i and -e $pod ) {
-        $file = $pod;
-    }
+	# We don't support the reall old versions
+	unless ( $version >= 5.005 ) {
+		die "Module::Install only supports 5.005 or newer (use ExtUtils::MakeMaker)\n";
+	}
 
-    $self->author_from($file)   unless $self->author;
-    $self->license_from($file)  unless $self->license;
-    $self->abstract_from($file) unless $self->abstract;
+	$self->{values}->{perl_version} = $version;
 }
 
-sub provides {
-    my $self     = shift;
-    my $provides = ( $self->{values}{provides} ||= {} );
-    %$provides = (%$provides, @_) if @_;
-    return $provides;
-}
+sub all_from {
+	my ( $self, $file ) = @_;
+
+	unless ( defined($file) ) {
+		my $name = $self->name or die(
+			"all_from called with no args without setting name() first"
+		);
+		$file = join('/', 'lib', split(/-/, $name)) . '.pm';
+		$file =~ s{.*/}{} unless -e $file;
+		unless ( -e $file ) {
+			die("all_from cannot find $file from $name");
+		}
+	}
+	unless ( -f $file ) {
+		die("The path '$file' does not exist, or is not a file");
+	}
 
-sub auto_provides {
-    my $self = shift;
-    return $self unless $self->is_admin;
+	$self->{values}{all_from} = $file;
 
-    unless (-e 'MANIFEST') {
-        warn "Cannot deduce auto_provides without a MANIFEST, skipping\n";
-        return $self;
-    }
+	# Some methods pull from POD instead of code.
+	# If there is a matching .pod, use that instead
+	my $pod = $file;
+	$pod =~ s/\.pm$/.pod/i;
+	$pod = $file unless -e $pod;
 
-    # Avoid spurious warnings as we are not checking manifest here.
+	# Pull the different values
+	$self->name_from($file)         unless $self->name;
+	$self->version_from($file)      unless $self->version;
+	$self->perl_version_from($file) unless $self->perl_version;
+	$self->author_from($pod)        unless @{$self->author || []};
+	$self->license_from($pod)       unless $self->license;
+	$self->abstract_from($pod)      unless $self->abstract;
 
-    local $SIG{__WARN__} = sub {1};
-    require ExtUtils::Manifest;
-    local *ExtUtils::Manifest::manicheck = sub { return };
+	return 1;
+}
 
-    require Module::Build;
-    my $build = Module::Build->new(
-        dist_name    => $self->name,
-        dist_version => $self->version,
-        license      => $self->license,
-    );
-    $self->provides(%{ $build->find_dist_packages || {} });
+sub provides {
+	my $self     = shift;
+	my $provides = ( $self->{values}->{provides} ||= {} );
+	%$provides = (%$provides, @_) if @_;
+	return $provides;
+}
+
+sub auto_provides {
+	my $self = shift;
+	return $self unless $self->is_admin;
+	unless (-e 'MANIFEST') {
+		warn "Cannot deduce auto_provides without a MANIFEST, skipping\n";
+		return $self;
+	}
+	# Avoid spurious warnings as we are not checking manifest here.
+	local $SIG{__WARN__} = sub {1};
+	require ExtUtils::Manifest;
+	local *ExtUtils::Manifest::manicheck = sub { return };
+
+	require Module::Build;
+	my $build = Module::Build->new(
+		dist_name    => $self->name,
+		dist_version => $self->version,
+		license      => $self->license,
+	);
+	$self->provides( %{ $build->find_dist_packages || {} } );
 }
 
 sub feature {
-    my $self     = shift;
-    my $name     = shift;
-    my $features = ( $self->{values}{features} ||= [] );
-
-    my $mods;
-
-    if ( @_ == 1 and ref( $_[0] ) ) {
-        # The user used ->feature like ->features by passing in the second
-        # argument as a reference.  Accomodate for that.
-        $mods = $_[0];
-    } else {
-        $mods = \@_;
-    }
+	my $self     = shift;
+	my $name     = shift;
+	my $features = ( $self->{values}->{features} ||= [] );
+	my $mods;
+
+	if ( @_ == 1 and ref( $_[0] ) ) {
+		# The user used ->feature like ->features by passing in the second
+		# argument as a reference.  Accomodate for that.
+		$mods = $_[0];
+	} else {
+		$mods = \@_;
+	}
 
-    my $count = 0;
-    push @$features, (
-        $name => [
-            map {
-                ref($_) ? ( ref($_) eq 'HASH' ) ? %$_
-                                                : @$_
-                        : $_
-            } @$mods
-        ]
-    );
+	my $count = 0;
+	push @$features, (
+		$name => [
+			map {
+				ref($_) ? ( ref($_) eq 'HASH' ) ? %$_ : @$_ : $_
+			} @$mods
+		]
+	);
 
-    return @$features;
+	return @$features;
 }
 
 sub features {
-    my $self = shift;
-    while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
-        $self->feature( $name, @$mods );
-    }
-    return $self->{values}->{features}
-    	? @{ $self->{values}->{features} }
-    	: ();
+	my $self = shift;
+	while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
+		$self->feature( $name, @$mods );
+	}
+	return $self->{values}->{features}
+		? @{ $self->{values}->{features} }
+		: ();
 }
 
 sub no_index {
-    my $self = shift;
-    my $type = shift;
-    push @{ $self->{values}{no_index}{$type} }, @_ if $type;
-    return $self->{values}{no_index};
+	my $self = shift;
+	my $type = shift;
+	push @{ $self->{values}->{no_index}->{$type} }, @_ if $type;
+	return $self->{values}->{no_index};
 }
 
 sub read {
-    my $self = shift;
-    $self->include_deps( 'YAML', 0 );
-
-    require YAML;
-    my $data = YAML::LoadFile('META.yml');
-
-    # Call methods explicitly in case user has already set some values.
-    while ( my ( $key, $value ) = each %$data ) {
-        next unless $self->can($key);
-        if ( ref $value eq 'HASH' ) {
-            while ( my ( $module, $version ) = each %$value ) {
-                $self->can($key)->($self, $module => $version );
-            }
-        }
-        else {
-            $self->can($key)->($self, $value);
-        }
-    }
-    return $self;
+	my $self = shift;
+	$self->include_deps( 'YAML::Tiny', 0 );
+
+	require YAML::Tiny;
+	my $data = YAML::Tiny::LoadFile('META.yml');
+
+	# Call methods explicitly in case user has already set some values.
+	while ( my ( $key, $value ) = each %$data ) {
+		next unless $self->can($key);
+		if ( ref $value eq 'HASH' ) {
+			while ( my ( $module, $version ) = each %$value ) {
+				$self->can($key)->($self, $module => $version );
+			}
+		} else {
+			$self->can($key)->($self, $value);
+		}
+	}
+	return $self;
 }
 
 sub write {
-    my $self = shift;
-    return $self unless $self->is_admin;
-    $self->admin->write_meta;
-    return $self;
+	my $self = shift;
+	return $self unless $self->is_admin;
+	$self->admin->write_meta;
+	return $self;
 }
 
 sub version_from {
-    my ( $self, $file ) = @_;
-    require ExtUtils::MM_Unix;
-    $self->version( ExtUtils::MM_Unix->parse_version($file) );
+	require ExtUtils::MM_Unix;
+	my ( $self, $file ) = @_;
+	$self->version( ExtUtils::MM_Unix->parse_version($file) );
+
+	# for version integrity check
+	$self->makemaker_args( VERSION_FROM => $file );
 }
 
 sub abstract_from {
-    my ( $self, $file ) = @_;
-    require ExtUtils::MM_Unix;
-    $self->abstract(
-        bless(
-            { DISTNAME => $self->name },
-            'ExtUtils::MM_Unix'
-        )->parse_abstract($file)
-     );
+	require ExtUtils::MM_Unix;
+	my ( $self, $file ) = @_;
+	$self->abstract(
+		bless(
+			{ DISTNAME => $self->name },
+			'ExtUtils::MM_Unix'
+		)->parse_abstract($file)
+	);
 }
 
-sub _slurp {
-    my ( $self, $file ) = @_;
+# Add both distribution and module name
+sub name_from {
+	my ($self, $file) = @_;
+	if (
+		Module::Install::_read($file) =~ m/
+		^ \s*
+		package \s*
+		([\w:]+)
+		\s* ;
+		/ixms
+	) {
+		my ($name, $module_name) = ($1, $1);
+		$name =~ s{::}{-}g;
+		$self->name($name);
+		unless ( $self->module_name ) {
+			$self->module_name($module_name);
+		}
+	} else {
+		die("Cannot determine name from $file\n");
+	}
+}
 
-    local *FH;
-    open FH, "< $file" or die "Cannot open $file.pod: $!";
-    do { local $/; <FH> };
+sub _extract_perl_version {
+	if (
+		$_[0] =~ m/
+		^\s*
+		(?:use|require) \s*
+		v?
+		([\d_\.]+)
+		\s* ;
+		/ixms
+	) {
+		my $perl_version = $1;
+		$perl_version =~ s{_}{}g;
+		return $perl_version;
+	} else {
+		return;
+	}
 }
 
 sub perl_version_from {
-    my ( $self, $file ) = @_;
-
-    if (
-        $self->_slurp($file) =~ m/
-        ^
-        use \s*
-        v?
-        ([\d_\.]+)
-        \s* ;
-    /ixms
-      )
-    {
-        my $v = $1;
-        $v =~ s{_}{}g;
-        $self->perl_version($1);
-    }
-    else {
-        warn "Cannot determine perl version info from $file\n";
-        return;
-    }
+	my $self = shift;
+	my $perl_version=_extract_perl_version(Module::Install::_read($_[0]));
+	if ($perl_version) {
+		$self->perl_version($perl_version);
+	} else {
+		warn "Cannot determine perl version info from $_[0]\n";
+		return;
+	}
 }
 
 sub author_from {
-    my ( $self, $file ) = @_;
-    my $content = $self->_slurp($file);
-    if ($content =~ m/
-        =head \d \s+ (?:authors?)\b \s*
-        ([^\n]*)
-        |
-        =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s*
-        .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s*
-        ([^\n]*)
-    /ixms) {
-        my $author = $1 || $2;
-        $author =~ s{E<lt>}{<}g;
-        $author =~ s{E<gt>}{>}g;
-        $self->author($author); 
-    }
-    else {
-        warn "Cannot determine author info from $file\n";
-    }
+	my $self    = shift;
+	my $content = Module::Install::_read($_[0]);
+	if ($content =~ m/
+		=head \d \s+ (?:authors?)\b \s*
+		([^\n]*)
+		|
+		=head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s*
+		.*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s*
+		([^\n]*)
+	/ixms) {
+		my $author = $1 || $2;
+
+		# XXX: ugly but should work anyway...
+		if (eval "require Pod::Escapes; 1") {
+			# Pod::Escapes has a mapping table.
+			# It's in core of perl >= 5.9.3, and should be installed
+			# as one of the Pod::Simple's prereqs, which is a prereq
+			# of Pod::Text 3.x (see also below).
+			$author =~ s{ E<( (\d+) | ([A-Za-z]+) )> }
+			{
+				defined $2
+				? chr($2)
+				: defined $Pod::Escapes::Name2character_number{$1}
+				? chr($Pod::Escapes::Name2character_number{$1})
+				: do {
+					warn "Unknown escape: E<$1>";
+					"E<$1>";
+				};
+			}gex;
+		}
+		elsif (eval "require Pod::Text; 1" && $Pod::Text::VERSION < 3) {
+			# Pod::Text < 3.0 has yet another mapping table,
+			# though the table name of 2.x and 1.x are different.
+			# (1.x is in core of Perl < 5.6, 2.x is in core of
+			# Perl < 5.9.3)
+			my $mapping = ($Pod::Text::VERSION < 2)
+				? \%Pod::Text::HTML_Escapes
+				: \%Pod::Text::ESCAPES;
+			$author =~ s{ E<( (\d+) | ([A-Za-z]+) )> }
+			{
+				defined $2
+				? chr($2)
+				: defined $mapping->{$1}
+				? $mapping->{$1}
+				: do {
+					warn "Unknown escape: E<$1>";
+					"E<$1>";
+				};
+			}gex;
+		}
+		else {
+			$author =~ s{E<lt>}{<}g;
+			$author =~ s{E<gt>}{>}g;
+		}
+		$self->author($author);
+	} else {
+		warn "Cannot determine author info from $_[0]\n";
+	}
+}
+
+#Stolen from M::B
+my %license_urls = (
+    perl         => 'http://dev.perl.org/licenses/',
+    apache       => 'http://apache.org/licenses/LICENSE-2.0',
+    apache_1_1   => 'http://apache.org/licenses/LICENSE-1.1',
+    artistic     => 'http://opensource.org/licenses/artistic-license.php',
+    artistic_2   => 'http://opensource.org/licenses/artistic-license-2.0.php',
+    lgpl         => 'http://opensource.org/licenses/lgpl-license.php',
+    lgpl2        => 'http://opensource.org/licenses/lgpl-2.1.php',
+    lgpl3        => 'http://opensource.org/licenses/lgpl-3.0.html',
+    bsd          => 'http://opensource.org/licenses/bsd-license.php',
+    gpl          => 'http://opensource.org/licenses/gpl-license.php',
+    gpl2         => 'http://opensource.org/licenses/gpl-2.0.php',
+    gpl3         => 'http://opensource.org/licenses/gpl-3.0.html',
+    mit          => 'http://opensource.org/licenses/mit-license.php',
+    mozilla      => 'http://opensource.org/licenses/mozilla1.1.php',
+    open_source  => undef,
+    unrestricted => undef,
+    restrictive  => undef,
+    unknown      => undef,
+);
+
+sub license {
+	my $self = shift;
+	return $self->{values}->{license} unless @_;
+	my $license = shift or die(
+		'Did not provide a value to license()'
+	);
+	$license = __extract_license($license) || lc $license;
+	$self->{values}->{license} = $license;
+
+	# Automatically fill in license URLs
+	if ( $license_urls{$license} ) {
+		$self->resources( license => $license_urls{$license} );
+	}
+
+	return 1;
+}
+
+sub _extract_license {
+	my $pod = shift;
+	my $matched;
+	return __extract_license(
+		($matched) = $pod =~ m/
+			(=head \d \s+ L(?i:ICEN[CS]E|ICENSING)\b.*?)
+			(=head \d.*|=cut.*|)\z
+		/xms
+	) || __extract_license(
+		($matched) = $pod =~ m/
+			(=head \d \s+ (?:C(?i:OPYRIGHTS?)|L(?i:EGAL))\b.*?)
+			(=head \d.*|=cut.*|)\z
+		/xms
+	);
+}
+
+sub __extract_license {
+	my $license_text = shift or return;
+	my @phrases      = (
+		'(?:under )?the same (?:terms|license) as (?:perl|the perl (?:\d )?programming language)' => 'perl', 1,
+		'(?:under )?the terms of (?:perl|the perl programming language) itself' => 'perl', 1,
+		'Artistic and GPL'                   => 'perl',         1,
+		'GNU general public license'         => 'gpl',          1,
+		'GNU public license'                 => 'gpl',          1,
+		'GNU lesser general public license'  => 'lgpl',         1,
+		'GNU lesser public license'          => 'lgpl',         1,
+		'GNU library general public license' => 'lgpl',         1,
+		'GNU library public license'         => 'lgpl',         1,
+		'GNU Free Documentation license'     => 'unrestricted', 1,
+		'GNU Affero General Public License'  => 'open_source',  1,
+		'(?:Free)?BSD license'               => 'bsd',          1,
+		'Artistic license'                   => 'artistic',     1,
+		'Apache (?:Software )?license'       => 'apache',       1,
+		'GPL'                                => 'gpl',          1,
+		'LGPL'                               => 'lgpl',         1,
+		'BSD'                                => 'bsd',          1,
+		'Artistic'                           => 'artistic',     1,
+		'MIT'                                => 'mit',          1,
+		'Mozilla Public License'             => 'mozilla',      1,
+		'Q Public License'                   => 'open_source',  1,
+		'OpenSSL License'                    => 'unrestricted', 1,
+		'SSLeay License'                     => 'unrestricted', 1,
+		'zlib License'                       => 'open_source',  1,
+		'proprietary'                        => 'proprietary',  0,
+	);
+	while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) {
+		$pattern =~ s#\s+#\\s+#gs;
+		if ( $license_text =~ /\b$pattern\b/i ) {
+			return $license;
+		}
+	}
+	return '';
 }
 
 sub license_from {
-    my ( $self, $file ) = @_;
-
-    if (
-        $self->_slurp($file) =~ m/
-        (
-            =head \d \s+
-            (?:licen[cs]e|licensing|copyright|legal)\b
-            .*?
-        )
-        (=head\\d.*|=cut.*|)
-        \z
-    /ixms
-      )
-    {
-        my $license_text = $1;
-        my @phrases      = (
-            'under the same (?:terms|license) as perl itself' => 'perl',
-            'GNU public license'                              => 'gpl',
-            'GNU lesser public license'                       => 'gpl',
-            'BSD license'                                     => 'bsd',
-            'Artistic license'                                => 'artistic',
-            'GPL'                                             => 'gpl',
-            'LGPL'                                            => 'lgpl',
-            'BSD'                                             => 'bsd',
-            'Artistic'                                        => 'artistic',
-            'MIT'                                             => 'MIT',
-        );
-        while ( my ( $pattern, $license ) = splice( @phrases, 0, 2 ) ) {
-            $pattern =~ s{\s+}{\\s+}g;
-            if ( $license_text =~ /\b$pattern\b/i ) {
-                $self->license($license);
-                return 1;
-            }
-        }
+	my $self = shift;
+	if (my $license=_extract_license(Module::Install::_read($_[0]))) {
+		$self->license($license);
+	} else {
+		warn "Cannot determine license info from $_[0]\n";
+		return 'unknown';
+	}
+}
+
+sub _extract_bugtracker {
+	my @links   = $_[0] =~ m#L<(
+	 \Qhttp://rt.cpan.org/\E[^>]+|
+	 \Qhttp://github.com/\E[\w_]+/[\w_]+/issues|
+	 \Qhttp://code.google.com/p/\E[\w_\-]+/issues/list
+	 )>#gx;
+	my %links;
+	@links{@links}=();
+	@links=keys %links;
+	return @links;
+}
+
+sub bugtracker_from {
+	my $self    = shift;
+	my $content = Module::Install::_read($_[0]);
+	my @links   = _extract_bugtracker($content);
+	unless ( @links ) {
+		warn "Cannot determine bugtracker info from $_[0]\n";
+		return 0;
+	}
+	if ( @links > 1 ) {
+		warn "Found more than one bugtracker link in $_[0]\n";
+		return 0;
+	}
+
+	# Set the bugtracker
+	bugtracker( $links[0] );
+	return 1;
+}
+
+sub requires_from {
+	my $self     = shift;
+	my $content  = Module::Install::_readperl($_[0]);
+	my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg;
+	while ( @requires ) {
+		my $module  = shift @requires;
+		my $version = shift @requires;
+		$self->requires( $module => $version );
+	}
+}
+
+sub test_requires_from {
+	my $self     = shift;
+	my $content  = Module::Install::_readperl($_[0]);
+	my @requires = $content =~ m/^use\s+([^\W\d]\w*(?:::\w+)*)\s+([\d\.]+)/mg;
+	while ( @requires ) {
+		my $module  = shift @requires;
+		my $version = shift @requires;
+		$self->test_requires( $module => $version );
+	}
+}
+
+# Convert triple-part versions (eg, 5.6.1 or 5.8.9) to
+# numbers (eg, 5.006001 or 5.008009).
+# Also, convert double-part versions (eg, 5.8)
+sub _perl_version {
+	my $v = $_[-1];
+	$v =~ s/^([1-9])\.([1-9]\d?\d?)$/sprintf("%d.%03d",$1,$2)/e;
+	$v =~ s/^([1-9])\.([1-9]\d?\d?)\.(0|[1-9]\d?\d?)$/sprintf("%d.%03d%03d",$1,$2,$3 || 0)/e;
+	$v =~ s/(\.\d\d\d)000$/$1/;
+	$v =~ s/_.+$//;
+	if ( ref($v) ) {
+		# Numify
+		$v = $v + 0;
+	}
+	return $v;
+}
+
+sub add_metadata {
+    my $self = shift;
+    my %hash = @_;
+    for my $key (keys %hash) {
+        warn "add_metadata: $key is not prefixed with 'x_'.\n" .
+             "Use appopriate function to add non-private metadata.\n" unless $key =~ /^x_/;
+        $self->{values}->{$key} = $hash{$key};
     }
+}
+
+
+######################################################################
+# MYMETA Support
+
+sub WriteMyMeta {
+	die "WriteMyMeta has been deprecated";
+}
+
+sub write_mymeta_yaml {
+	my $self = shift;
+
+	# We need YAML::Tiny to write the MYMETA.yml file
+	unless ( eval { require YAML::Tiny; 1; } ) {
+		return 1;
+	}
+
+	# Generate the data
+	my $meta = $self->_write_mymeta_data or return 1;
+
+	# Save as the MYMETA.yml file
+	print "Writing MYMETA.yml\n";
+	YAML::Tiny::DumpFile('MYMETA.yml', $meta);
+}
+
+sub write_mymeta_json {
+	my $self = shift;
+
+	# We need JSON to write the MYMETA.json file
+	unless ( eval { require JSON; 1; } ) {
+		return 1;
+	}
+
+	# Generate the data
+	my $meta = $self->_write_mymeta_data or return 1;
+
+	# Save as the MYMETA.yml file
+	print "Writing MYMETA.json\n";
+	Module::Install::_write(
+		'MYMETA.json',
+		JSON->new->pretty(1)->canonical->encode($meta),
+	);
+}
+
+sub _write_mymeta_data {
+	my $self = shift;
+
+	# If there's no existing META.yml there is nothing we can do
+	return undef unless -f 'META.yml';
+
+	# We need Parse::CPAN::Meta to load the file
+	unless ( eval { require Parse::CPAN::Meta; 1; } ) {
+		return undef;
+	}
+
+	# Merge the perl version into the dependencies
+	my $val  = $self->Meta->{values};
+	my $perl = delete $val->{perl_version};
+	if ( $perl ) {
+		$val->{requires} ||= [];
+		my $requires = $val->{requires};
+
+		# Canonize to three-dot version after Perl 5.6
+		if ( $perl >= 5.006 ) {
+			$perl =~ s{^(\d+)\.(\d\d\d)(\d*)}{join('.', $1, int($2||0), int($3||0))}e
+		}
+		unshift @$requires, [ perl => $perl ];
+	}
+
+	# Load the advisory META.yml file
+	my @yaml = Parse::CPAN::Meta::LoadFile('META.yml');
+	my $meta = $yaml[0];
+
+	# Overwrite the non-configure dependency hashs
+	delete $meta->{requires};
+	delete $meta->{build_requires};
+	delete $meta->{recommends};
+	if ( exists $val->{requires} ) {
+		$meta->{requires} = { map { @$_ } @{ $val->{requires} } };
+	}
+	if ( exists $val->{build_requires} ) {
+		$meta->{build_requires} = { map { @$_ } @{ $val->{build_requires} } };
+	}
 
-    warn "Cannot determine license info from $file\n";
-    return 'unknown';
+	return $meta;
 }
 
 1;
@@ -2,13 +2,13 @@
 package Module::Install::Win32;
 
 use strict;
-use Module::Install::Base;
+use Module::Install::Base ();
 
-use vars qw{$VERSION $ISCORE @ISA};
+use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.65';
+	$VERSION = '0.99';
+	@ISA     = 'Module::Install::Base';
 	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
 }
 
 # determine if the user needs nmake, and download it if needed
@@ -16,7 +16,7 @@ sub check_nmake {
 	my $self = shift;
 	$self->load('can_run');
 	$self->load('get_file');
-	
+
 	require Config;
 	return unless (
 		$^O eq 'MSWin32'                     and
@@ -38,8 +38,7 @@ sub check_nmake {
 		remove    => 1,
 	);
 
-	if (!$rv) {
-        die <<'END_MESSAGE';
+	die <<'END_MESSAGE' unless $rv;
 
 -------------------------------------------------------------------------------
 
@@ -59,7 +58,7 @@ You may then resume the installation process described in README.
 
 -------------------------------------------------------------------------------
 END_MESSAGE
-	}
+
 }
 
 1;
@@ -2,42 +2,62 @@
 package Module::Install::WriteAll;
 
 use strict;
-use Module::Install::Base;
+use Module::Install::Base ();
 
-use vars qw{$VERSION $ISCORE @ISA};
+use vars qw{$VERSION @ISA $ISCORE};
 BEGIN {
-	$VERSION = '0.65';
-	$ISCORE  = 1;
+	$VERSION = '0.99';
 	@ISA     = qw{Module::Install::Base};
+	$ISCORE  = 1;
 }
 
 sub WriteAll {
-    my $self = shift;
-    my %args = (
-        meta        => 1,
-        sign        => 0,
-        inline      => 0,
-        check_nmake => 1,
-        @_
-    );
-
-    $self->sign(1)                if $args{sign};
-    $self->Meta->write            if $args{meta};
-    $self->admin->WriteAll(%args) if $self->is_admin;
-
-    if ( $0 =~ /Build.PL$/i ) {
-        $self->Build->write;
-    } else {
-        $self->check_nmake if $args{check_nmake};
-        unless ( $self->makemaker_args->{'PL_FILES'} ) {
-        	$self->makemaker_args( PL_FILES => {} );
-        }
-        if ($args{inline}) {
-            $self->Inline->write;
-        } else {
-            $self->Makefile->write;
-        }
-    }
+	my $self = shift;
+	my %args = (
+		meta        => 1,
+		sign        => 0,
+		inline      => 0,
+		check_nmake => 1,
+		@_,
+	);
+
+	$self->sign(1)                if $args{sign};
+	$self->admin->WriteAll(%args) if $self->is_admin;
+
+	$self->check_nmake if $args{check_nmake};
+	unless ( $self->makemaker_args->{PL_FILES} ) {
+		# XXX: This still may be a bit over-defensive...
+		unless ($self->makemaker(6.25)) {
+			$self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL';
+		}
+	}
+
+	# Until ExtUtils::MakeMaker support MYMETA.yml, make sure
+	# we clean it up properly ourself.
+	$self->realclean_files('MYMETA.yml');
+
+	if ( $args{inline} ) {
+		$self->Inline->write;
+	} else {
+		$self->Makefile->write;
+	}
+
+	# The Makefile write process adds a couple of dependencies,
+	# so write the META.yml files after the Makefile.
+	if ( $args{meta} ) {
+		$self->Meta->write;
+	}
+
+	# Experimental support for MYMETA
+	if ( $ENV{X_MYMETA} ) {
+		if ( $ENV{X_MYMETA} eq 'JSON' ) {
+			$self->Meta->write_mymeta_json;
+		} else {
+			$self->Meta->write_mymeta_yaml;
+		}
+	}
+
+	return 1;
 }
 
 1;
@@ -17,163 +17,245 @@ package Module::Install;
 #     3. The ./inc/ version of Module::Install loads
 # }
 
-use 5.004;
+use 5.005;
 use strict 'vars';
+use Cwd        ();
+use File::Find ();
+use File::Path ();
 
-use vars qw{$VERSION};
+use vars qw{$VERSION $MAIN};
 BEGIN {
-    # All Module::Install core packages now require synchronised versions.
-    # This will be used to ensure we don't accidentally load old or
-    # different versions of modules.
-    # This is not enforced yet, but will be some time in the next few
-    # releases once we can make sure it won't clash with custom
-    # Module::Install extensions.
-    $VERSION = '0.65';
+	# All Module::Install core packages now require synchronised versions.
+	# This will be used to ensure we don't accidentally load old or
+	# different versions of modules.
+	# This is not enforced yet, but will be some time in the next few
+	# releases once we can make sure it won't clash with custom
+	# Module::Install extensions.
+	$VERSION = '0.99';
+
+	# Storage for the pseudo-singleton
+	$MAIN    = undef;
+
+	*inc::Module::Install::VERSION = *VERSION;
+	@inc::Module::Install::ISA     = __PACKAGE__;
+
 }
 
-# Whether or not inc::Module::Install is actually loaded, the
-# $INC{inc/Module/Install.pm} is what will still get set as long as
-# the caller loaded module this in the documented manner.
-# If not set, the caller may NOT have loaded the bundled version, and thus
-# they may not have a MI version that works with the Makefile.PL. This would
-# result in false errors or unexpected behaviour. And we don't want that.
-my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
-unless ( $INC{$file} ) {
-    die <<"END_DIE";
+sub import {
+	my $class = shift;
+	my $self  = $class->new(@_);
+	my $who   = $self->_caller;
+
+	#-------------------------------------------------------------
+	# all of the following checks should be included in import(),
+	# to allow "eval 'require Module::Install; 1' to test
+	# installation of Module::Install. (RT #51267)
+	#-------------------------------------------------------------
+
+	# Whether or not inc::Module::Install is actually loaded, the
+	# $INC{inc/Module/Install.pm} is what will still get set as long as
+	# the caller loaded module this in the documented manner.
+	# If not set, the caller may NOT have loaded the bundled version, and thus
+	# they may not have a MI version that works with the Makefile.PL. This would
+	# result in false errors or unexpected behaviour. And we don't want that.
+	my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
+	unless ( $INC{$file} ) { die <<"END_DIE" }
+
 Please invoke ${\__PACKAGE__} with:
 
-    use inc::${\__PACKAGE__};
+	use inc::${\__PACKAGE__};
 
 not:
 
-    use ${\__PACKAGE__};
+	use ${\__PACKAGE__};
 
 END_DIE
-}
 
-# If the script that is loading Module::Install is from the future,
-# then make will detect this and cause it to re-run over and over
-# again. This is bad. Rather than taking action to touch it (which
-# is unreliable on some platforms and requires write permissions)
-# for now we should catch this and refuse to run.
-if ( -f $0 and (stat($0))[9] > time ) {
-	die << "END_DIE";
-Your installer $0 has a modification time in the future.
+	# This reportedly fixes a rare Win32 UTC file time issue, but
+	# as this is a non-cross-platform XS module not in the core,
+	# we shouldn't really depend on it. See RT #24194 for detail.
+	# (Also, this module only supports Perl 5.6 and above).
+	eval "use Win32::UTCFileTime" if $^O eq 'MSWin32' && $] >= 5.006;
+
+	# If the script that is loading Module::Install is from the future,
+	# then make will detect this and cause it to re-run over and over
+	# again. This is bad. Rather than taking action to touch it (which
+	# is unreliable on some platforms and requires write permissions)
+	# for now we should catch this and refuse to run.
+	if ( -f $0 ) {
+		my $s = (stat($0))[9];
+
+		# If the modification time is only slightly in the future,
+		# sleep briefly to remove the problem.
+		my $a = $s - time;
+		if ( $a > 0 and $a < 5 ) { sleep 5 }
+
+		# Too far in the future, throw an error.
+		my $t = time;
+		if ( $s > $t ) { die <<"END_DIE" }
+
+Your installer $0 has a modification time in the future ($s > $t).
 
 This is known to create infinite loops in make.
 
 Please correct this, then run $0 again.
 
 END_DIE
-}
+	}
 
-use Cwd        ();
-use File::Find ();
-use File::Path ();
-use FindBin;
 
-*inc::Module::Install::VERSION = *VERSION;
-@inc::Module::Install::ISA     = __PACKAGE__;
+	# Build.PL was formerly supported, but no longer is due to excessive
+	# difficulty in implementing every single feature twice.
+	if ( $0 =~ /Build.PL$/i ) { die <<"END_DIE" }
 
-sub autoload {
-    my $self = shift;
-    my $who  = $self->_caller;
-    my $cwd  = Cwd::cwd();
-    my $sym  = "${who}::AUTOLOAD";
-    $sym->{$cwd} = sub {
-        my $pwd = Cwd::cwd();
-        if ( my $code = $sym->{$pwd} ) {
-            # delegate back to parent dirs
-            goto &$code unless $cwd eq $pwd;
-        }
-        $$sym =~ /([^:]+)$/ or die "Cannot autoload $who - $sym";
-        unshift @_, ($self, $1);
-        goto &{$self->can('call')} unless uc($1) eq $1;
-    };
+Module::Install no longer supports Build.PL.
+
+It was impossible to maintain duel backends, and has been deprecated.
+
+Please remove all Build.PL files and only use the Makefile.PL installer.
+
+END_DIE
+
+	#-------------------------------------------------------------
+
+	# To save some more typing in Module::Install installers, every...
+	# use inc::Module::Install
+	# ...also acts as an implicit use strict.
+	$^H |= strict::bits(qw(refs subs vars));
+
+	#-------------------------------------------------------------
+
+	unless ( -f $self->{file} ) {
+		foreach my $key (keys %INC) {
+			delete $INC{$key} if $key =~ /Module\/Install/;
+		}
+
+		local $^W;
+		require "$self->{path}/$self->{dispatch}.pm";
+		File::Path::mkpath("$self->{prefix}/$self->{author}");
+		$self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
+		$self->{admin}->init;
+		@_ = ($class, _self => $self);
+		goto &{"$self->{name}::import"};
+	}
+
+	local $^W;
+	*{"${who}::AUTOLOAD"} = $self->autoload;
+	$self->preload;
+
+	# Unregister loader and worker packages so subdirs can use them again
+	delete $INC{'inc/Module/Install.pm'};
+	delete $INC{'Module/Install.pm'};
+
+	# Save to the singleton
+	$MAIN = $self;
+
+	return 1;
 }
 
-sub import {
-    my $class = shift;
-    my $self  = $class->new(@_);
-    my $who   = $self->_caller;
-
-    unless ( -f $self->{file} ) {
-        require "$self->{path}/$self->{dispatch}.pm";
-        File::Path::mkpath("$self->{prefix}/$self->{author}");
-        $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
-        $self->{admin}->init;
-        @_ = ($class, _self => $self);
-        goto &{"$self->{name}::import"};
-    }
-
-    *{"${who}::AUTOLOAD"} = $self->autoload;
-    $self->preload;
-
-    # Unregister loader and worker packages so subdirs can use them again
-    delete $INC{"$self->{file}"};
-    delete $INC{"$self->{path}.pm"};
+sub autoload {
+	my $self = shift;
+	my $who  = $self->_caller;
+	my $cwd  = Cwd::cwd();
+	my $sym  = "${who}::AUTOLOAD";
+	$sym->{$cwd} = sub {
+		my $pwd = Cwd::cwd();
+		if ( my $code = $sym->{$pwd} ) {
+			# Delegate back to parent dirs
+			goto &$code unless $cwd eq $pwd;
+		}
+		unless ($$sym =~ s/([^:]+)$//) {
+			# XXX: it looks like we can't retrieve the missing function
+			# via $$sym (usually $main::AUTOLOAD) in this case.
+			# I'm still wondering if we should slurp Makefile.PL to
+			# get some context or not ...
+			my ($package, $file, $line) = caller;
+			die <<"EOT";
+Unknown function is found at $file line $line.
+Execution of $file aborted due to runtime errors.
+
+If you're a contributor to a project, you may need to install
+some Module::Install extensions from CPAN (or other repository).
+If you're a user of a module, please contact the author.
+EOT
+		}
+		my $method = $1;
+		if ( uc($method) eq $method ) {
+			# Do nothing
+			return;
+		} elsif ( $method =~ /^_/ and $self->can($method) ) {
+			# Dispatch to the root M:I class
+			return $self->$method(@_);
+		}
+
+		# Dispatch to the appropriate plugin
+		unshift @_, ( $self, $1 );
+		goto &{$self->can('call')};
+	};
 }
 
 sub preload {
-    my ($self) = @_;
-
-    unless ( $self->{extensions} ) {
-        $self->load_extensions(
-            "$self->{prefix}/$self->{path}", $self
-        );
-    }
-
-    my @exts = @{$self->{extensions}};
-    unless ( @exts ) {
-        my $admin = $self->{admin};
-        @exts = $admin->load_all_extensions;
-    }
-
-    my %seen;
-    foreach my $obj ( @exts ) {
-        while (my ($method, $glob) = each %{ref($obj) . '::'}) {
-            next unless $obj->can($method);
-            next if $method =~ /^_/;
-            next if $method eq uc($method);
-            $seen{$method}++;
-        }
-    }
-
-    my $who = $self->_caller;
-    foreach my $name ( sort keys %seen ) {
-        *{"${who}::$name"} = sub {
-            ${"${who}::AUTOLOAD"} = "${who}::$name";
-            goto &{"${who}::AUTOLOAD"};
-        };
-    }
+	my $self = shift;
+	unless ( $self->{extensions} ) {
+		$self->load_extensions(
+			"$self->{prefix}/$self->{path}", $self
+		);
+	}
+
+	my @exts = @{$self->{extensions}};
+	unless ( @exts ) {
+		@exts = $self->{admin}->load_all_extensions;
+	}
+
+	my %seen;
+	foreach my $obj ( @exts ) {
+		while (my ($method, $glob) = each %{ref($obj) . '::'}) {
+			next unless $obj->can($method);
+			next if $method =~ /^_/;
+			next if $method eq uc($method);
+			$seen{$method}++;
+		}
+	}
+
+	my $who = $self->_caller;
+	foreach my $name ( sort keys %seen ) {
+		local $^W;
+		*{"${who}::$name"} = sub {
+			${"${who}::AUTOLOAD"} = "${who}::$name";
+			goto &{"${who}::AUTOLOAD"};
+		};
+	}
 }
 
 sub new {
-    my ($class, %args) = @_;
-
-    # ignore the prefix on extension modules built from top level.
-    my $base_path = Cwd::abs_path($FindBin::Bin);
-    unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
-        delete $args{prefix};
-    }
-
-    return $args{_self} if $args{_self};
-
-    $args{dispatch} ||= 'Admin';
-    $args{prefix}   ||= 'inc';
-    $args{author}   ||= ($^O eq 'VMS' ? '_author' : '.author');
-    $args{bundle}   ||= 'inc/BUNDLES';
-    $args{base}     ||= $base_path;
-    $class =~ s/^\Q$args{prefix}\E:://;
-    $args{name}     ||= $class;
-    $args{version}  ||= $class->VERSION;
-    unless ( $args{path} ) {
-        $args{path}  = $args{name};
-        $args{path}  =~ s!::!/!g;
-    }
-    $args{file}     ||= "$args{base}/$args{prefix}/$args{path}.pm";
-
-    bless( \%args, $class );
+	my ($class, %args) = @_;
+
+    delete $INC{'FindBin.pm'};
+    require FindBin;
+
+	# ignore the prefix on extension modules built from top level.
+	my $base_path = Cwd::abs_path($FindBin::Bin);
+	unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
+		delete $args{prefix};
+	}
+	return $args{_self} if $args{_self};
+
+	$args{dispatch} ||= 'Admin';
+	$args{prefix}   ||= 'inc';
+	$args{author}   ||= ($^O eq 'VMS' ? '_author' : '.author');
+	$args{bundle}   ||= 'inc/BUNDLES';
+	$args{base}     ||= $base_path;
+	$class =~ s/^\Q$args{prefix}\E:://;
+	$args{name}     ||= $class;
+	$args{version}  ||= $class->VERSION;
+	unless ( $args{path} ) {
+		$args{path}  = $args{name};
+		$args{path}  =~ s!::!/!g;
+	}
+	$args{file}     ||= "$args{base}/$args{prefix}/$args{path}.pm";
+	$args{wrote}      = 0;
+
+	bless( \%args, $class );
 }
 
 sub call {
@@ -184,98 +266,201 @@ sub call {
 }
 
 sub load {
-    my ($self, $method) = @_;
+	my ($self, $method) = @_;
 
-    $self->load_extensions(
-        "$self->{prefix}/$self->{path}", $self
-    ) unless $self->{extensions};
+	$self->load_extensions(
+		"$self->{prefix}/$self->{path}", $self
+	) unless $self->{extensions};
 
-    foreach my $obj (@{$self->{extensions}}) {
-        return $obj if $obj->can($method);
-    }
+	foreach my $obj (@{$self->{extensions}}) {
+		return $obj if $obj->can($method);
+	}
 
-    my $admin = $self->{admin} or die <<"END_DIE";
+	my $admin = $self->{admin} or die <<"END_DIE";
 The '$method' method does not exist in the '$self->{prefix}' path!
 Please remove the '$self->{prefix}' directory and run $0 again to load it.
 END_DIE
 
-    my $obj = $admin->load($method, 1);
-    push @{$self->{extensions}}, $obj;
+	my $obj = $admin->load($method, 1);
+	push @{$self->{extensions}}, $obj;
 
-    $obj;
+	$obj;
 }
 
 sub load_extensions {
-    my ($self, $path, $top) = @_;
-
-    unless ( grep { lc $_ eq lc $self->{prefix} } @INC ) {
-        unshift @INC, $self->{prefix};
-    }
-
-    foreach my $rv ( $self->find_extensions($path) ) {
-        my ($file, $pkg) = @{$rv};
-        next if $self->{pathnames}{$pkg};
-
-        local $@;
-        my $new = eval { require $file; $pkg->can('new') };
-        unless ( $new ) {
-            warn $@ if $@;
-            next;
-        }
-        $self->{pathnames}{$pkg} = delete $INC{$file};
-        push @{$self->{extensions}}, &{$new}($pkg, _top => $top );
-    }
-
-    $self->{extensions} ||= [];
+	my ($self, $path, $top) = @_;
+
+	my $should_reload = 0;
+	unless ( grep { ! ref $_ and lc $_ eq lc $self->{prefix} } @INC ) {
+		unshift @INC, $self->{prefix};
+		$should_reload = 1;
+	}
+
+	foreach my $rv ( $self->find_extensions($path) ) {
+		my ($file, $pkg) = @{$rv};
+		next if $self->{pathnames}{$pkg};
+
+		local $@;
+		my $new = eval { local $^W; require $file; $pkg->can('new') };
+		unless ( $new ) {
+			warn $@ if $@;
+			next;
+		}
+		$self->{pathnames}{$pkg} =
+			$should_reload ? delete $INC{$file} : $INC{$file};
+		push @{$self->{extensions}}, &{$new}($pkg, _top => $top );
+	}
+
+	$self->{extensions} ||= [];
 }
 
 sub find_extensions {
-    my ($self, $path) = @_;
-
-    my @found;
-    File::Find::find( sub {
-        my $file = $File::Find::name;
-        return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
-        my $subpath = $1;
-        return if lc($subpath) eq lc($self->{dispatch});
-
-        $file = "$self->{path}/$subpath.pm";
-        my $pkg = "$self->{name}::$subpath";
-        $pkg =~ s!/!::!g;
-
-        # If we have a mixed-case package name, assume case has been preserved
-        # correctly.  Otherwise, root through the file to locate the case-preserved
-        # version of the package name.
-        if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
-            open PKGFILE, "<$subpath.pm" or die "find_extensions: Can't open $subpath.pm: $!";
-            my $in_pod = 0;
-            while ( <PKGFILE> ) {
-                $in_pod = 1 if /^=\w/;
-                $in_pod = 0 if /^=cut/;
-                next if ($in_pod || /^=cut/);  # skip pod text
-                next if /^\s*#/;               # and comments
-                if ( m/^\s*package\s+($pkg)\s*;/i ) {
-                    $pkg = $1;
-                    last;
-                }
-            }
-            close PKGFILE;
-        }
-
-        push @found, [ $file, $pkg ];
-    }, $path ) if -d $path;
-
-    @found;
+	my ($self, $path) = @_;
+
+	my @found;
+	File::Find::find( sub {
+		my $file = $File::Find::name;
+		return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
+		my $subpath = $1;
+		return if lc($subpath) eq lc($self->{dispatch});
+
+		$file = "$self->{path}/$subpath.pm";
+		my $pkg = "$self->{name}::$subpath";
+		$pkg =~ s!/!::!g;
+
+		# If we have a mixed-case package name, assume case has been preserved
+		# correctly.  Otherwise, root through the file to locate the case-preserved
+		# version of the package name.
+		if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
+			my $content = Module::Install::_read($subpath . '.pm');
+			my $in_pod  = 0;
+			foreach ( split //, $content ) {
+				$in_pod = 1 if /^=\w/;
+				$in_pod = 0 if /^=cut/;
+				next if ($in_pod || /^=cut/);  # skip pod text
+				next if /^\s*#/;               # and comments
+				if ( m/^\s*package\s+($pkg)\s*;/i ) {
+					$pkg = $1;
+					last;
+				}
+			}
+		}
+
+		push @found, [ $file, $pkg ];
+	}, $path ) if -d $path;
+
+	@found;
 }
 
+
+
+
+
+#####################################################################
+# Common Utility Functions
+
 sub _caller {
-    my $depth = 0;
-    my $call  = caller($depth);
-    while ( $call eq __PACKAGE__ ) {
-        $depth++;
-        $call = caller($depth);
-    }
-    return $call;
+	my $depth = 0;
+	my $call  = caller($depth);
+	while ( $call eq __PACKAGE__ ) {
+		$depth++;
+		$call = caller($depth);
+	}
+	return $call;
+}
+
+# Done in evals to avoid confusing Perl::MinimumVersion
+eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
+sub _read {
+	local *FH;
+	open( FH, '<', $_[0] ) or die "open($_[0]): $!";
+	my $string = do { local $/; <FH> };
+	close FH or die "close($_[0]): $!";
+	return $string;
+}
+END_NEW
+sub _read {
+	local *FH;
+	open( FH, "< $_[0]"  ) or die "open($_[0]): $!";
+	my $string = do { local $/; <FH> };
+	close FH or die "close($_[0]): $!";
+	return $string;
+}
+END_OLD
+
+sub _readperl {
+	my $string = Module::Install::_read($_[0]);
+	$string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg;
+	$string =~ s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s;
+	$string =~ s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg;
+	return $string;
+}
+
+sub _readpod {
+	my $string = Module::Install::_read($_[0]);
+	$string =~ s/(?:\015{1,2}\012|\015|\012)/\n/sg;
+	return $string if $_[0] =~ /\.pod\z/;
+	$string =~ s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg;
+	$string =~ s/\n*=pod\b[^\n]*\n+/\n\n/sg;
+	$string =~ s/\n*=cut\b[^\n]*\n+/\n\n/sg;
+	$string =~ s/^\n+//s;
+	return $string;
+}
+
+# Done in evals to avoid confusing Perl::MinimumVersion
+eval( $] >= 5.006 ? <<'END_NEW' : <<'END_OLD' ); die $@ if $@;
+sub _write {
+	local *FH;
+	open( FH, '>', $_[0] ) or die "open($_[0]): $!";
+	foreach ( 1 .. $#_ ) {
+		print FH $_[$_] or die "print($_[0]): $!";
+	}
+	close FH or die "close($_[0]): $!";
+}
+END_NEW
+sub _write {
+	local *FH;
+	open( FH, "> $_[0]"  ) or die "open($_[0]): $!";
+	foreach ( 1 .. $#_ ) {
+		print FH $_[$_] or die "print($_[0]): $!";
+	}
+	close FH or die "close($_[0]): $!";
+}
+END_OLD
+
+# _version is for processing module versions (eg, 1.03_05) not
+# Perl versions (eg, 5.8.1).
+sub _version ($) {
+	my $s = shift || 0;
+	my $d =()= $s =~ /(\.)/g;
+	if ( $d >= 2 ) {
+		# Normalise multipart versions
+		$s =~ s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/eg;
+	}
+	$s =~ s/^(\d+)\.?//;
+	my $l = $1 || 0;
+	my @v = map {
+		$_ . '0' x (3 - length $_)
+	} $s =~ /(\d{1,3})\D?/g;
+	$l = $l . '.' . join '', @v if @v;
+	return $l + 0;
+}
+
+sub _cmp ($$) {
+	_version($_[0]) <=> _version($_[1]);
+}
+
+# Cloned from Params::Util::_CLASS
+sub _CLASS ($) {
+	(
+		defined $_[0]
+		and
+		! ref $_[0]
+		and
+		$_[0] =~ m/^[^\W\d]\w*(?:::\w+)*\z/s
+	) ? $_[0] : undef;
 }
 
 1;
+
+# Copyright 2008 - 2010 Adam Kennedy.
@@ -14,7 +14,7 @@ use constant MP2 => (
            $ENV{MOD_PERL_API_VERSION} >= 2
 );
 
-our $VERSION = '1.12';
+our $VERSION = '1.14';
 
 __PACKAGE__->mk_accessors(qw/apache return/);
 
@@ -47,6 +47,7 @@ sub prepare_connection {
     $c->request->hostname( $self->apache->connection->remote_host );
     $c->request->protocol( $self->apache->protocol );
     $c->request->user( $self->apache->user );
+    $c->request->remote_user( $self->apache->user );
 
     # when config options are set, check them here first
     if ($INC{'Apache2/ModSSL.pm'}) {
@@ -301,29 +302,37 @@ by adding this to your configuration:
 
     PerlSetVar CatalystDisableLocationMatch 1
 
+=head2 NOTES ON NON-STANDARD PORTS
+
+If you wish to run your site on a non-standard port you will need to use the
+C<Port> Apache config rather than C<Listen>. This will result in the correct
+port being added to urls created using C<uri_for>.
+
+    Port 8080
+
 =head1 OVERLOADED METHODS
 
 This class overloads some methods from C<Catalyst::Engine>.
 
 =over 4
 
-=item $c->engine->prepare_request($r)
+=item prepare_request($r)
 
-=item $c->engine->prepare_connection
+=item prepare_connection
 
-=item $c->engine->prepare_query_parameters
+=item prepare_query_parameters
 
-=item $c->engine->prepare_headers
+=item prepare_headers
 
-=item $c->engine->prepare_path
+=item prepare_path
 
-=item $c->engine->read_chunk
+=item read_chunk
 
-=item $c->engine->finalize_body
+=item finalize_body
 
-=item $c->engine->finalize_headers
+=item finalize_headers
 
-=item $c->engine->write
+=item write
 
 =back
 
@@ -0,0 +1,49 @@
+***************
+*** 307,329 ****
+  
+  =over 4
+  
+- =item $c->engine->prepare_request($r)
+  
+- =item $c->engine->prepare_connection
+  
+- =item $c->engine->prepare_query_parameters
+  
+- =item $c->engine->prepare_headers
+  
+- =item $c->engine->prepare_path
+  
+- =item $c->engine->read_chunk
+  
+- =item $c->engine->finalize_body
+  
+- =item $c->engine->finalize_headers
+  
+- =item $c->engine->write
+  
+  =back
+  
+--- 307,329 ----
+  
+  =over 4
+  
++ =item prepare_request($r)
+  
++ =item prepare_connection
+  
++ =item prepare_query_parameters
+  
++ =item prepare_headers
+  
++ =item prepare_path
+  
++ =item read_chunk
+  
++ =item finalize_body
+  
++ =item finalize_headers
+  
++ =item write
+  
+  =back
+  
@@ -54,10 +54,26 @@ Catalyst::Engine::Apache2::MP19 - Catalyst Apache2 mod_perl 1.99x Engine
         </Location>
         
         # Make sure to let Apache handle your static files
-        # (And remember to remove the Static::Simple plugin in production)
+        # (It is not necessary to remove the Static::Simple plugin 
+        # in production; Apache will bypass Static::Simple if
+        # configured in this way)
+
         <Location /static>
             SetHandler          default-handler
-        </Location>   
+        </Location>
+ 
+        # If not running at a root location in a VirtualHost,
+        # you'll probably need to set an Alias to the location
+        # of your static files, and allow access to this location:
+
+        Alias /myapp/static /filesystem/path/to/MyApp/root/static
+        <Directory /filesystem/path/to/MyApp/root/static>
+            allow from all
+        </Directory>
+        <Location /myapp/static>
+            SetHandler default-handler
+        </Location>
+
     </VirtualHost>
 
 =head1 DESCRIPTION
@@ -56,10 +56,26 @@ Catalyst::Engine::Apache2::MP20 - Catalyst Apache2 mod_perl 2.x Engine
         </Location>
         
         # Make sure to let Apache handle your static files
-        # (And remember to remove the Static::Simple plugin in production)
+        # (It is not necessary to remove the Static::Simple plugin 
+        # in production; Apache will bypass Static::Simple if
+        # configured in this way)
+
         <Location /static>
             SetHandler          default-handler
         </Location>
+ 
+        # If not running at a root location in a VirtualHost,
+        # you'll probably need to set an Alias to the location
+        # of your static files, and allow access to this location:
+
+        Alias /myapp/static /filesystem/path/to/MyApp/root/static
+        <Directory /filesystem/path/to/MyApp/root/static>
+            allow from all
+        </Directory>
+        <Location /myapp/static>
+            SetHandler default-handler
+        </Location>
+
     </VirtualHost>
 
 =head1 DESCRIPTION
@@ -99,6 +115,26 @@ script/myapp_registry.pl (you will need to create this):
 
 =head2 ok_constant
 
+=head1 OVERLOADED METHODS
+
+This class overloads some methods from C<Catalyst::Engine>.
+
+=over 4
+
+=item unescape_uri 
+
+=back
+
+=head1 OVERLOADED METHODS
+
+This class overloads some methods from C<Catalyst::Engine>.
+
+=over 4
+
+=item unescape_uri 
+
+=back
+
 =head1 SEE ALSO
 
 L<Catalyst>, L<Catalyst::Engine>, L<Catalyst::Engine::Apache2>.
@@ -40,7 +40,7 @@ This class overloads some methods from C<Catalyst::Engine>.
 
 =over 4
 
-=item $c->engine->finalize_headers
+=item finalize_headers
 
 =back
 
@@ -0,0 +1,17 @@
+***************
+*** 40,46 ****
+  
+  =over 4
+  
+- =item $c->engine->finalize_headers
+  
+  =back
+  
+--- 40,46 ----
+  
+  =over 4
+  
++ =item finalize_headers
+  
+  =back
+  
@@ -0,0 +1,9 @@
+use strict;
+use warnings;
+
+use Test::More;
+
+use_ok 'Catalyst::Engine::Apache';
+
+done_testing;
+
@@ -1,7 +0,0 @@
-use Test::More;
-
-eval "use Test::Pod 1.14";
-plan skip_all => 'Test::Pod 1.14 required' if $@;
-plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD};
-
-all_pod_files_ok();
@@ -1,7 +0,0 @@
-use Test::More;
-
-eval "use Test::Pod::Coverage 1.04";
-plan skip_all => 'Test::Pod::Coverage 1.04 required' if $@;
-plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD};
-
-all_pod_coverage_ok();
@@ -0,0 +1,110 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 28 * $iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        ok( my $response = request('http://localhost/action_action_one'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action_action_one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Action',
+            'Test Class'
+        );
+        is( $response->header('X-Action'), 'works' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action_action_two'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action_action_two', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Action',
+            'Test Class'
+        );
+        is( $response->header('X-Action-After'), 'awesome' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok(
+            my $response =
+              request('http://localhost/action_action_three/one/two'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action_action_three', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Action',
+            'Test Class'
+        );
+        is( $response->header('X-TestAppActionTestBefore'), 'one' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action_action_four'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action_action_four', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Action',
+            'Test Class'
+        );
+        is( $response->header('X-TestAppActionTestMyAction'), 'MyAction works' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+}
@@ -0,0 +1,136 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 18*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+    
+    # new dispatcher:
+    # 11 wallclock secs (10.14 usr +  0.20 sys = 10.34 CPU) @ 15.18/s (n=157)
+    # old dispatcher (r1486):
+    # 11 wallclock secs (10.34 usr +  0.20 sys = 10.54 CPU) @ 13.76/s (n=145)
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+    
+sub run_tests {
+    # test auto + local method
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto->one
+          TestApp::Controller::Root->end
+        ];
+    
+        my $expected = join( ", ", @expected );
+    
+        ok( my $response = request('http://localhost/action/auto/one'), 'auto + local' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'one', 'Content OK' );
+    }
+    
+    # test auto + default
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto->default
+          TestApp::Controller::Root->end
+        ];
+    
+        my $expected = join( ", ", @expected );
+    
+        ok( my $response = request('http://localhost/action/auto/anything'), 'auto + default' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'default', 'Content OK' );
+    }
+    
+    # test auto + auto + local
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto::Deep->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto::Deep->auto
+          TestApp::Controller::Action::Auto::Deep->one
+          TestApp::Controller::Root->end
+        ];
+    
+        my $expected = join( ", ", @expected );
+    
+        ok( my $response = request('http://localhost/action/auto/deep/one'), 'auto + auto + local' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'deep one', 'Content OK' );
+    }
+    
+    # test auto + auto + default
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto::Deep->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto::Deep->auto
+          TestApp::Controller::Action::Auto::Deep->default
+          TestApp::Controller::Root->end
+        ];
+    
+        my $expected = join( ", ", @expected );
+    
+        ok( my $response = request('http://localhost/action/auto/deep/anything'), 'auto + auto + default' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'deep default', 'Content OK' );
+    }
+    
+    # test auto + failing auto + local + end
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto::Abort->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto::Abort->auto
+          TestApp::Controller::Action::Auto::Abort->end
+        ];
+    
+        my $expected = join( ", ", @expected );
+    
+        ok( my $response = request('http://localhost/action/auto/abort/one'), 'auto + failing auto + local' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'abort end', 'Content OK' );
+    }
+    
+    # test auto + default (bug on invocation of default twice)
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Auto::Default->begin
+          TestApp::Controller::Action::Auto->auto
+          TestApp::Controller::Action::Auto::Default->auto
+          TestApp::Controller::Action::Auto::Default->default
+          TestApp::Controller::Action::Auto::Default->end
+        ];
+    
+        my $expected = join( ", ", @expected );
+    
+        ok( my $response = request('http://localhost/action/auto/default/moose'), 'auto + default' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'default (auto: 1)', 'Content OK' );
+    }
+}
@@ -0,0 +1,53 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 7*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Begin->begin
+          TestApp::Controller::Action::Begin->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/begin'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Begin',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like( $response->content, qr/'Catalyst::Request'/,
+            'Content is a serialized Catalyst::Request' );
+    }
+}
@@ -0,0 +1,831 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 118*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests($_);
+    }
+}
+
+sub run_tests {
+    my ($run_number) = @_;
+
+    #
+    #   This is a simple test where the parent and child actions are
+    #   within the same controller.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->foo
+          TestApp::Controller::Action::Chained->endpoint
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/foo/1/end/2'), 'chained + local endpoint' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   This makes sure the above isn't found if the argument for the
+    #   end action isn't supplied.
+    #
+    {
+        my $expected = undef;
+
+        ok( my $response = request('http://localhost/chained/foo/1/end'), 
+            'chained + local endpoint; missing last argument' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->code, 500, 'Status OK' );
+    }
+
+    #
+    #   Tests the case when the child action is placed in a subcontroller.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->foo
+          TestApp::Controller::Action::Chained::Foo->spoon
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/foo/1/spoon'), 'chained + subcontroller endpoint' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; ', 'Content OK' );
+    }
+
+    #
+    #   Tests if the relative specification (e.g.: Chained('bar') ) works
+    #   as expected.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->bar
+          TestApp::Controller::Action::Chained->finale
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/bar/1/spoon'), 'chained + relative endpoint' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 1, spoon', 'Content OK' );
+    }
+
+    #
+    #   Just a test for multiple arguments.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->foo2
+          TestApp::Controller::Action::Chained->endpoint2
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/foo2/10/20/end2/15/25'), 
+            'chained + local (2 args each)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '10, 20; 15, 25', 'Content OK' );
+    }
+
+    #
+    #   The first three-chain test tries to call the action with :Args(1)
+    #   specification. There's also a one action with a :CaptureArgs(1)
+    #   attribute, that should not be dispatched to.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->one_end
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/one/23'),
+            'three-chain (only first)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 23', 'Content OK' );
+    }
+
+    #
+    #   This is the second three-chain test, it goes for the action that
+    #   handles "/one/$cap/two/$arg1/$arg2" paths. Should be the two action
+    #   having :Args(2), not the one having :CaptureArgs(2).
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->one
+          TestApp::Controller::Action::Chained->two_end
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/one/23/two/23/46'),
+            'three-chain (up to second)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '23; 23, 46', 'Content OK' );
+    }
+
+    #
+    #   Last of the three-chain tests. Has no concurrent action with :CaptureArgs
+    #   and is more thought to simply test the chain as a whole and the 'two'
+    #   action specifying :CaptureArgs.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->one
+          TestApp::Controller::Action::Chained->two
+          TestApp::Controller::Action::Chained->three_end
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/one/23/two/23/46/three/1/2/3'),
+            'three-chain (all three)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '23, 23, 46; 1, 2, 3', 'Content OK' );
+    }
+
+    #
+    #   Tests dispatching on number of arguments for :Args. This should be
+    #   dispatched to the action expecting one argument.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->multi1
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/multi/23'),
+            'multi-action (one arg)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 23', 'Content OK' );
+    }
+
+    #
+    #   Belongs to the former test and goes for the action expecting two arguments.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->multi2
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/multi/23/46'),
+            'multi-action (two args)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 23, 46', 'Content OK' );
+    }
+
+    #
+    #   Dispatching on argument count again, this time we provide too many
+    #   arguments, so dispatching should fail.
+    #
+    {
+        my $expected = undef;
+
+        ok( my $response = request('http://localhost/chained/multi/23/46/67'),
+            'multi-action (three args, should lead to error)' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->code, 500, 'Status OK' );
+    }
+
+    #
+    #   This tests the case when an action says it's the child of an action in
+    #   a subcontroller.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Foo->higher_root
+          TestApp::Controller::Action::Chained->higher_root
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/higher_root/23/bar/11'),
+            'root higher than child' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '23; 11', 'Content OK' );
+    }
+
+    #
+    #   Just a more complex version of the former test. It tests if a controller ->
+    #   subcontroller -> controller dispatch works.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->pcp1
+          TestApp::Controller::Action::Chained::Foo->pcp2
+          TestApp::Controller::Action::Chained->pcp3
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/pcp1/1/pcp2/2/pcp3/3'),
+            'parent -> child -> parent' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1, 2; 3', 'Content OK' );
+    }
+
+    #
+    #   Tests dispatch on capture number. This test is for a one capture action.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->multi_cap1
+          TestApp::Controller::Action::Chained->multi_cap_end1
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/multi_cap/1/baz'),
+            'dispatch on capture num 1' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; ', 'Content OK' );
+    }
+
+    #
+    #   Belongs to the former test. This one goes for the action expecting two
+    #   captures.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->multi_cap2
+          TestApp::Controller::Action::Chained->multi_cap_end2
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/multi_cap/1/2/baz'),
+            'dispatch on capture num 2' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1, 2; ', 'Content OK' );
+    }
+
+    #
+    #   Tests the priority of a slurpy arguments action (with :Args) against
+    #   two actions chained together. The two actions should win.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->priority_a2
+          TestApp::Controller::Action::Chained->priority_a2_end
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/priority_a/1/end/2'),
+            'priority - slurpy args vs. parent/child' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   This belongs to the former test but tests if two chained actions have
+    #   priority over an action with the exact arguments.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->priority_b2
+          TestApp::Controller::Action::Chained->priority_b2_end
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/priority_b/1/end/2'),
+            'priority - fixed args vs. parent/child' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   This belongs to the former test but tests if two chained actions have
+    #   priority over an action with one child action not having the Args() attr set.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->priority_c1
+          TestApp::Controller::Action::Chained->priority_c2_xyz
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/priority_c/1/xyz/'),
+            'priority - no Args() order mismatch' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; ', 'Content OK' );
+    }
+
+    #
+    #   Test dispatching between two controllers that are on the same level and
+    #   therefor have no parent/child relationship.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Bar->cross1
+          TestApp::Controller::Action::Chained::Foo->cross2
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/cross/1/end/2'),
+            'cross controller w/o par/child relation' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   This is for testing if the arguments got passed to the actions 
+    #   correctly.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::PassedArgs->first
+          TestApp::Controller::Action::Chained::PassedArgs->second
+          TestApp::Controller::Action::Chained::PassedArgs->third
+          TestApp::Controller::Action::Chained::PassedArgs->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/passedargs/a/1/b/2/c/3'),
+            'Correct arguments passed to actions' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2; 3', 'Content OK' );
+    }
+
+    #
+    #   The :Args attribute is optional, we check the action not specifying
+    #   it with these tests.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->opt_args
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/opt_args/1/2/3'),
+            'Optional :Args attribute working' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 1, 2, 3', 'Content OK' );
+    }
+
+    #
+    #   Tests for optional PathPart attribute.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->opt_pp_start
+          TestApp::Controller::Action::Chained->opt_pathpart
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/optpp/1/opt_pathpart/2'),
+            'Optional :PathName attribute working' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Tests for optional PathPart *and* Args attributes.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->opt_all_start
+          TestApp::Controller::Action::Chained->oa
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/optall/1/oa/2/3'),
+            'Optional :PathName *and* :Args attributes working' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2, 3', 'Content OK' );
+    }
+
+    #
+    #   Test if :Chained is the same as :Chained('/')
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->rootdef
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/rootdef/23'),
+            ":Chained is the same as :Chained('/')" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; 23', 'Content OK' );
+    }
+
+    #
+    #   Test if :Chained('.') is working
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->parentchain
+          TestApp::Controller::Action::Chained::ParentChain->child
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/parentchain/1/child/2'),
+            ":Chained('.') chains to parent controller action" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test behaviour of auto actions returning '1' for the chain.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Auto->auto
+          TestApp::Controller::Action::Chained::Auto::Foo->auto
+          TestApp::Controller::Action::Chained::Auto->foo
+          TestApp::Controller::Action::Chained::Auto::Foo->fooend
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/autochain1/1/fooend/2'),
+            "Behaviour when auto returns 1 correct" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test behaviour of auto actions returning '0' for the chain.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Auto->auto
+          TestApp::Controller::Action::Chained::Auto::Bar->auto
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/autochain2/1/barend/2'),
+            "Behaviour when auto returns 0 correct" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test what auto actions are run when namespaces are changed
+    #   horizontally.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Auto->auto
+          TestApp::Controller::Action::Chained::Auto::Foo->auto
+          TestApp::Controller::Action::Chained::Auto::Bar->crossloose
+          TestApp::Controller::Action::Chained::Auto::Foo->crossend
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/auto_cross/1/crossend/2'),
+            "Correct auto actions are run on cross controller dispatch" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test forwarding from auto action in chain dispatch.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Auto->auto
+          TestApp::Controller::Action::Chained::Auto::Forward->auto
+          TestApp::Controller::Action::Chained::Auto->fw3
+          TestApp::Controller::Action::Chained::Auto->fw1
+          TestApp::Controller::Action::Chained::Auto::Forward->forwardend
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/auto_forward/1/forwardend/2'),
+            "Forwarding out of auto in chain" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Detaching out of the auto action of a chain.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained::Auto->auto
+          TestApp::Controller::Action::Chained::Auto::Detach->auto
+          TestApp::Controller::Action::Chained::Auto->fw3
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/auto_detach/1/detachend/2'),
+            "Detaching out of auto in chain" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test forwarding from auto action in chain dispatch.
+    #
+    {
+        my $expected = undef;
+
+        ok( my $response = request('http://localhost/chained/loose/23'),
+            "Loose end is not callable" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->code, 500, 'Status OK' );
+    }
+
+    #
+    #   Test forwarding out of a chain.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->chain_fw_a
+          TestApp::Controller::Action::Chained->fw_dt_target
+          TestApp::Controller::Action::Chained->chain_fw_b
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/chain_fw/1/end/2'),
+            "Forwarding out a chain" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Test detaching out of a chain.
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->chain_dt_a
+          TestApp::Controller::Action::Chained->fw_dt_target
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/chain_dt/1/end/2'),
+            "Forwarding out a chain" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '1; 2', 'Content OK' );
+    }
+
+    #
+    #   Tests that an uri_for to a chained root index action
+    #   returns the right value.
+    #
+    {
+        ok( my $response = request(
+            'http://localhost/action/chained/to_root' ),
+            'uri_for with chained root action as arg' );
+        like( $response->content,
+            qr(URI:https?://[^/]+/),
+            'Correct URI generated' );
+    }
+
+    #
+    #   Test interception of recursive chains. This test was added because at
+    #   one point during the :Chained development, Catalyst used to hang on
+    #   recursive chains.
+    #
+    {
+        eval { require 'TestAppChainedRecursive.pm' };
+        if ($run_number == 1) {
+            ok( ! $@, "Interception of recursive chains" );
+        }
+        else { pass( "Interception of recursive chains already tested" ) }
+    }
+
+    #
+    #   Test failure of absolute path part arguments.
+    #
+    {
+        eval { require 'TestAppChainedAbsolutePathPart.pm' };
+        if ($run_number == 1) {
+            like( $@, qr(foo/foo),
+                "Usage of absolute path part argument emits error" );
+        }
+        else { pass( "Error on absolute path part arguments already tested" ) }
+    }
+
+    #
+    #   Test chained actions in the root controller
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained::Root->rootsub
+          TestApp::Controller::Action::Chained::Root->endpointsub
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/rootsub/1/endpointsub/2'), 'chained in root namespace' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '', 'Content OK' );
+    }
+
+    #
+    #   Complex path with multiple empty pathparts
+    #
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Chained->begin
+          TestApp::Controller::Action::Chained->mult_nopp_base
+          TestApp::Controller::Action::Chained->mult_nopp_all
+          TestApp::Controller::Action::Chained->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/chained/mult_nopp'),
+            "Complex path with multiple empty pathparts" );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, '; ', 'Content OK' );
+    }
+
+	#
+	#	Higher Args() hiding more specific CaptureArgs chains sections
+	#
+	{
+		my @expected = qw[
+		  	TestApp::Controller::Action::Chained->begin
+		  	TestApp::Controller::Action::Chained->cc_base
+		  	TestApp::Controller::Action::Chained->cc_link
+		  	TestApp::Controller::Action::Chained->cc_anchor
+		  	TestApp::Controller::Action::Chained->end
+			];
+
+		my $expected = join ', ', @expected;
+
+		ok( my $response = request('http://localhost/chained/choose_capture/anchor.html'),
+			'Choose between an early Args() and a later more ideal chain' );
+		is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions');
+		is( $response->content => '; ', 'Content OK' );
+	}
+
+	#
+	#	Less specific chain not being seen correctly due to earlier looser capture
+	#
+	{
+		my @expected = qw[
+		  	TestApp::Controller::Action::Chained->begin
+		  	TestApp::Controller::Action::Chained->cc_base
+		  	TestApp::Controller::Action::Chained->cc_b
+		  	TestApp::Controller::Action::Chained->cc_b_link
+		  	TestApp::Controller::Action::Chained->cc_b_anchor
+		  	TestApp::Controller::Action::Chained->end
+			];
+
+		my $expected = join ', ', @expected;
+
+		ok( my $response = request('http://localhost/chained/choose_capture/b/a/anchor.html'),
+			'Choose between a more specific chain and an earlier looser one' );
+		is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions');
+		is( $response->content => 'a; ', 'Content OK' );
+	}
+
+	#
+	#	Check we get the looser one when it's the correct match
+	#
+	{
+		my @expected = qw[
+		  	TestApp::Controller::Action::Chained->begin
+		  	TestApp::Controller::Action::Chained->cc_base
+		  	TestApp::Controller::Action::Chained->cc_a
+		  	TestApp::Controller::Action::Chained->cc_a_link
+		  	TestApp::Controller::Action::Chained->cc_a_anchor
+		  	TestApp::Controller::Action::Chained->end
+			];
+
+		my $expected = join ', ', @expected;
+
+		ok( my $response = request('http://localhost/chained/choose_capture/a/a/anchor.html'),
+			'Choose between a more specific chain and an earlier looser one' );
+		is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions');
+		is( $response->content => 'a; anchor.html', 'Content OK' );
+	}
+
+}
@@ -0,0 +1,96 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 16 * $iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Default->begin
+          TestApp::Controller::Action::Default->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/default'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Default',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+
+        ok( $response = request('http://localhost/foo/bar/action'), 'Request' );
+        is( $response->code, 500, 'Invalid URI returned 500' );
+    }
+
+    # test that args are passed properly to default
+    {
+        my $creq;
+        my $expected = [qw/action default arg1 arg2/];
+
+        ok( my $response = request('http://localhost/action/default/arg1/arg2'),
+            'Request' );
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+        is_deeply( $creq->{arguments}, $expected, 'Arguments ok' );
+    }
+    
+    
+    # Test that /foo and /foo/ both do the same thing
+    {
+        my @expected = qw[
+          TestApp::Controller::Action->begin
+          TestApp::Controller::Action->default
+          TestApp::Controller::Root->end
+        ];
+        
+        my $expected = join( ", ", @expected );
+        
+        ok( my $response = request('http://localhost/action'), 'Request' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 
+            'Executed actions for /action'
+        );
+        
+        ok( $response = request('http://localhost/action/'), 'Request' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 
+            'Executed actions for /action/'
+        );
+    }   
+}
@@ -0,0 +1,100 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 18*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Detach->begin
+          TestApp::Controller::Action::Detach->one
+          TestApp::Controller::Action::Detach->two
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # Test detach to chain of actions.
+        ok( my $response = request('http://localhost/action/detach/one'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/detach/one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Detach',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+    }
+
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Detach->begin
+          TestApp::Controller::Action::Detach->path
+          TestApp::Controller::Action::Detach->two
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # Test detach to chain of actions.
+        ok( my $response = request('http://localhost/action/detach/path'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/detach/path', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Detach',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+    }
+
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/detach/with_args/old'),
+            'Request with args'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'new' );
+    }
+
+    {
+        ok(
+            my $response = request(
+                'http://localhost/action/detach/with_method_and_args/old'),
+            'Request with args and method'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'new' );
+    }
+}
@@ -0,0 +1,54 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 7*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::End->begin
+          TestApp::Controller::Action::End->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Action::End->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/end'), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::End',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+}
@@ -0,0 +1,238 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 47 * $iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Forward->begin
+          TestApp::Controller::Action::Forward->one
+          TestApp::Controller::Action::Forward->two
+          TestApp::Controller::Action::Forward->three
+          TestApp::Controller::Action::Forward->four
+          TestApp::Controller::Action::Forward->five
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # Test forward to global private action
+        ok( my $response = request('http://localhost/action/forward/global'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/forward/global', 'Main Class Action' );
+
+        # Test forward to chain of actions.
+        ok( $response = request('http://localhost/action/forward/one'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/forward/one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Forward',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Forward->begin
+          TestApp::Controller::Action::Forward->jojo
+          TestApp::Controller::Action::Forward->one
+          TestApp::Controller::Action::Forward->two
+          TestApp::Controller::Action::Forward->three
+          TestApp::Controller::Action::Forward->four
+          TestApp::Controller::Action::Forward->five
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Action::Forward->three
+          TestApp::Controller::Action::Forward->four
+          TestApp::Controller::Action::Forward->five
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/forward/jojo'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/forward/jojo', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Forward',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/forward/with_args/old'),
+            'Request with args'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'old' );
+    }
+
+    {
+        ok(
+            my $response = request(
+                'http://localhost/action/forward/with_method_and_args/old'),
+            'Request with args and method'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'old' );
+    }
+
+    # test forward with embedded args
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/forward/args_embed_relative'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'ok' );
+    }
+
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/forward/args_embed_absolute'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content, 'ok' );
+    }
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::TestRelative->begin
+          TestApp::Controller::Action::TestRelative->relative
+          TestApp::Controller::Action::Forward->one
+          TestApp::Controller::Action::Forward->two
+          TestApp::Controller::Action::Forward->three
+          TestApp::Controller::Action::Forward->four
+          TestApp::Controller::Action::Forward->five
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # Test forward to chain of actions.
+        ok( my $response = request('http://localhost/action/relative/relative'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/relative/relative', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::TestRelative',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::TestRelative->begin
+          TestApp::Controller::Action::TestRelative->relative_two
+          TestApp::Controller::Action::Forward->one
+          TestApp::Controller::Action::Forward->two
+          TestApp::Controller::Action::Forward->three
+          TestApp::Controller::Action::Forward->four
+          TestApp::Controller::Action::Forward->five
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Root->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        # Test forward to chain of actions.
+        ok(
+            my $response =
+              request('http://localhost/action/relative/relative_two'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is(
+            $response->header('X-Catalyst-Action'),
+            'action/relative/relative_two',
+            'Test Action'
+        );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::TestRelative',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    # test class forwards
+    {
+        ok(
+            my $response = request(
+                'http://localhost/action/forward/class_forward_test_action'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->header('X-Class-Forward-Test-Method'), 1,
+            'Test Method' );
+    }
+
+}
@@ -0,0 +1,83 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 18*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        ok( my $response = request('http://localhost/action_global_one'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action_global_one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Global',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action_global_two'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action_global_two', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Global',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action_global_three'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action_global_three', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Global',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+}
@@ -0,0 +1,100 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 20*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    # test root index
+    {
+        my @expected = qw[
+          TestApp::Controller::Root->index
+          TestApp::Controller::Root->end
+        ];
+    
+        my $expected = join( ", ", @expected );
+        ok( my $response = request('http://localhost/'), 'root index' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'root index', 'root index ok' );
+        
+        ok( $response = request('http://localhost'), 'root index no slash' );
+        is( $response->content, 'root index', 'root index no slash ok' );
+    }
+    
+    # test first-level controller index
+    {
+        my @expected = qw[
+          TestApp::Controller::Index->index
+          TestApp::Controller::Root->end
+        ];
+    
+        my $expected = join( ", ", @expected );
+        
+        ok( my $response = request('http://localhost/index/'), 'first-level controller index' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'Index index', 'first-level controller index ok' );
+        
+        ok( $response = request('http://localhost/index'), 'first-level controller index no slash' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'Index index', 'first-level controller index no slash ok' );        
+    }    
+    
+    # test second-level controller index
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Index->begin
+          TestApp::Controller::Action::Index->index
+          TestApp::Controller::Root->end
+        ];
+    
+        my $expected = join( ", ", @expected );
+        
+        ok( my $response = request('http://localhost/action/index/'), 'second-level controller index' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'Action-Index index', 'second-level controller index ok' );
+        
+        ok( $response = request('http://localhost/action/index'), 'second-level controller index no slash' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, 'Action-Index index', 'second-level controller index no slash ok' );        
+    }
+    
+    # test controller default when index is present
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Index->begin
+          TestApp::Controller::Action::Index->default
+          TestApp::Controller::Root->end
+        ];
+    
+        my $expected = join( ", ", @expected );
+        
+        ok( my $response = request('http://localhost/action/index/foo'), 'default with index' );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        is( $response->content, "Error - TestApp::Controller::Action\n", 'default with index ok' );
+    }
+}
@@ -0,0 +1,119 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 21*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Inheritance->begin
+          TestApp::Controller::Action::Inheritance->auto
+          TestApp::Controller::Action::Inheritance->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Action::Inheritance->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/inheritance'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Inheritance',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Inheritance::A->begin
+          TestApp::Controller::Action::Inheritance->auto
+          TestApp::Controller::Action::Inheritance::A->auto
+          TestApp::Controller::Action::Inheritance::A->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Action::Inheritance::A->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/inheritance/a'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Inheritance::A',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        my @expected = qw[
+          TestApp::Controller::Action::Inheritance::A::B->begin
+          TestApp::Controller::Action::Inheritance->auto
+          TestApp::Controller::Action::Inheritance::A->auto
+          TestApp::Controller::Action::Inheritance::A::B->auto
+          TestApp::Controller::Action::Inheritance::A::B->default
+          TestApp::View::Dump::Request->process
+          TestApp::Controller::Action::Inheritance::A::B->end
+        ];
+
+        my $expected = join( ", ", @expected );
+
+        ok( my $response = request('http://localhost/action/inheritance/a/b'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Inheritance::A::B',
+            'Test Class'
+        );
+        is( $response->header('X-Catalyst-Executed'),
+            $expected, 'Executed actions' );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+}
@@ -0,0 +1,138 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 32*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        ok( my $response = request('http://localhost/action/local/one'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/local/one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Local',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/local/two/1/2'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/local/two', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Local',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+         ok( my $response = request('http://localhost/action/local/two'),
+               'Request' );
+         ok( !$response->is_success, 'Request with wrong number of args failed' );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/local/three'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/local/three', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Local',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/local/four/five/six'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/local/four/five/six', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Local',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    SKIP:
+    { 
+        if ( $ENV{CATALYST_SERVER} ) {
+            skip "tests for %2F on remote server", 6;
+        }
+        
+        ok(
+            my $response =
+              request('http://localhost/action/local/one/foo%2Fbar'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/local/one', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Local',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr~arguments => \[\s*'foo/bar'\s*\]~,
+            "Parameters don't split on %2F"
+        );
+    }
+}
@@ -0,0 +1,71 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+my $content = q/foo
+bar
+baz
+/;
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 16*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    # Local
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/multipath/multipath'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content, $content, 'Content is a stream' );
+    }
+
+    # Global
+    {
+        ok( my $response = request('http://localhost/multipath'), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content, $content, 'Content is a stream' );
+    }
+
+    # Path('/multipath1')
+    {
+        ok( my $response = request('http://localhost/multipath1'), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content, $content, 'Content is a stream' );
+    }
+
+    # Path('multipath2')
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/multipath/multipath2'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content, $content, 'Content is a stream' );
+    }
+}
@@ -0,0 +1,127 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 30*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        ok(
+            my $response =
+              request('http://localhost/action/path/a%20path%20with%20spaces'),
+            'Request'
+        );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is(
+            $response->header('X-Catalyst-Action'),
+            'action/path/a%20path%20with%20spaces',
+            'Test Action'
+        );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Path',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/path/åäö'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/path/%C3%A5%C3%A4%C3%B6', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Path',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/path/'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/path', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Path',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/path/spaces_near_parens_singleq'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/path/spaces_near_parens_singleq', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Path',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/path/spaces_near_parens_doubleq'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            'action/path/spaces_near_parens_doubleq', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Path',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+}
@@ -0,0 +1,89 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 24*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        ok( my $response = request('http://localhost/action/private/one'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Private',
+            'Test Class'
+        );
+        is( $response->content, 'access denied', 'Access' );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/private/two'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Private',
+            'Test Class'
+        );
+        is( $response->content, 'access denied', 'Access' );
+    }
+
+    {
+        ok( my $response = request('http://localhost/three'), 'Request' );
+        ok( $response->is_error, 'Response Server Error 5xx' );
+        is( $response->content_type, 'text/html', 'Response Content-Type' );
+        like(
+            $response->header('X-Catalyst-Error'),
+            qr/^Unknown resource "three"/,
+            'Catalyst Error'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/private/four'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Private',
+            'Test Class'
+        );
+        is( $response->content, 'access denied', 'Access' );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/private/five'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Private',
+            'Test Class'
+        );
+        is( $response->content, 'access denied', 'Access' );
+    }
+}
@@ -0,0 +1,106 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 28*$iters;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    {
+        ok( my $response = request('http://localhost/action/regexp/10/hello'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            '^action/regexp/(\d+)/(\w+)$', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Regexp',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/regexp/hello/10'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            '^action/regexp/(\w+)/(\d+)$', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Regexp',
+            'Test Class'
+        );
+        like(
+            $response->content,
+            qr/^bless\( .* 'Catalyst::Request' \)$/s,
+            'Content is a serialized Catalyst::Request'
+        );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/regexp/mandatory'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            '^action/regexp/(mandatory)(/optional)?$', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Regexp',
+            'Test Class'
+        );
+        my $content = $response->content;
+        my $req = eval $content; 
+
+        is( scalar @{ $req->captures }, 2, 'number of captures' );
+        is( $req->captures->[ 0 ], 'mandatory', 'mandatory capture' );
+        ok( !defined $req->captures->[ 1 ], 'optional capture' );
+    }
+
+    {
+        ok( my $response = request('http://localhost/action/regexp/mandatory/optional'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->header('X-Catalyst-Action'),
+            '^action/regexp/(mandatory)(/optional)?$', 'Test Action' );
+        is(
+            $response->header('X-Test-Class'),
+            'TestApp::Controller::Action::Regexp',
+            'Test Class'
+        );
+        my $content = $response->content;
+        my $req = eval $content; 
+
+        is( scalar @{ $req->captures }, 2, 'number of captures' );
+        is( $req->captures->[ 0 ], 'mandatory', 'mandatory capture' );
+        is( $req->captures->[ 1 ], '/optional', 'optional capture' );
+    }
+}
@@ -0,0 +1,72 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
+
+use Test::More tests => 10*$iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    # test direct streaming
+    {
+        ok( my $response = request('http://localhost/streaming'), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        
+        SKIP:
+        {
+            if ( $ENV{CATALYST_SERVER} ) {
+                skip "Using remote server", 1;
+            }
+            
+            # XXX: Length should be undef here, but HTTP::Request::AsCGI sets it
+            is( $response->content_length, 12, 'Response Content-Length' );
+        }
+        
+        is( $response->content,, <<'EOF', 'Content is a stream' );
+foo
+bar
+baz
+EOF
+    }
+
+    # test streaming by passing a handle to $c->res->body
+  SKIP:
+    {
+        if ( $ENV{CATALYST_SERVER} ) {
+            skip "Using remote server", 5;
+        }
+
+        my $file = "$FindBin::Bin/../lib/TestApp/Controller/Action/Streaming.pm";
+        my $fh = IO::File->new( $file, 'r' );
+        my $buffer;
+        if ( defined $fh ) {
+            $fh->read( $buffer, 1024 );
+            $fh->close;
+        }
+
+        ok( my $response = request('http://localhost/action/streaming/body'),
+            'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content_length, -s $file, 'Response Content-Length' );
+        is( $response->content, $buffer, 'Content is read from filehandle' );
+    }
+}
@@ -0,0 +1,98 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use URI::Escape;
+
+our @paths;
+our $iters;
+
+BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1;
+
+    # add special paths to test here
+    @paths = (
+        # all reserved in uri's
+        qw~ : / ? [ ] @ ! $ & ' ( ) * + ; = ~, ',' , '#',
+
+        # unreserved
+        'a'..'z','A'..'Z',0..9,qw( - . _ ~ ),
+        " ",
+
+        # just to test %2F/%
+        [ qw~ / / ~ ],
+
+        # testing %25/%25
+        [ qw~ % % ~ ],
+    );
+}
+
+use Test::More tests => 6*@paths * $iters;
+use Catalyst::Test 'TestApp';
+
+if ( $ENV{CAT_BENCHMARK} ) {
+    require Benchmark;
+    Benchmark::timethis( $iters, \&run_tests );
+
+    # new dispatcher:
+    # 11 wallclock secs (10.14 usr +  0.20 sys = 10.34 CPU) @ 15.18/s (n=157)
+    # old dispatcher (r1486):
+    # 11 wallclock secs (10.34 usr +  0.20 sys = 10.54 CPU) @ 13.76/s (n=145)
+}
+else {
+    for ( 1 .. $iters ) {
+        run_tests();
+    }
+}
+
+sub run_tests {
+    run_test_for($_) for @paths;
+}
+
+sub run_test_for {
+    my $test = shift;
+
+    my $path;
+    if (ref $test) {
+        $path = join "/", map uri_escape($_), @$test;
+        $test = join '', @$test;
+    } else {
+        $path = uri_escape($test);
+    }
+    
+    SKIP:
+    {   
+        # Skip %2F, ., [, (, and ) tests on real webservers
+        # Both Apache and lighttpd don't seem to like these
+        if ( $ENV{CATALYST_SERVER} && $path =~ /(?:%2F|\.|%5B|\(|\))/ ) {
+            skip "Skipping $path tests on remote server", 6;
+        }
+
+        my $response;
+
+        ok( $response = request("http://localhost/args/args/$path"), "Requested args for path $path");
+
+        is( $response->content, $test, "$test as args" );
+
+        undef $response;
+
+        ok( $response = request("http://localhost/args/params/$path"), "Requested params for path $path");
+
+        is( $response->content, $test, "$test as params" );
+
+        undef $response;
+
+        if( $test =~ m{/} ) {
+            $test =~ s{/}{}g;
+            $path = uri_escape( $test ); 
+        }
+
+        ok( $response = request("http://localhost/chained/multi_cap/$path/baz"), "Requested capture for path $path");
+
+        is( $response->content, join( ', ', split( //, $test ) ) ."; ", "$test as capture" );
+    }
+}
+
@@ -0,0 +1,77 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 18;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+use HTTP::Headers;
+use HTTP::Request::Common;
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/dump/request/',
+        'Content-Type' => 'text/plain',
+        'Content'      => 'Hello Catalyst'
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like( $response->content, qr/'Catalyst::Request'/,
+        'Content is a serialized Catalyst::Request' );
+
+    {
+        no strict 'refs';
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+    }
+
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method,       'POST',       'Catalyst::Request method' );
+    is( $creq->content_type, 'text/plain', 'Catalyst::Request Content-Type' );
+    is( $creq->content_length, $request->content_length,
+        'Catalyst::Request Content-Length' );
+}
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/dump/request/',
+        'Content-Type' => 'text/plain',
+        'Content'      => 'x' x 100_000
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+
+    {
+        no strict 'refs';
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+    }
+
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method,       'POST',       'Catalyst::Request method' );
+    is( $creq->content_type, 'text/plain', 'Catalyst::Request Content-Type' );
+    is( $creq->content_length, $request->content_length,
+        'Catalyst::Request Content-Length' );
+}
@@ -0,0 +1,66 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 8;
+use Catalyst::Test 'TestAppOnDemand';
+
+use Catalyst::Request;
+use HTTP::Headers;
+use HTTP::Request::Common;
+
+# Test a simple POST request to make sure body parsing
+# works in on-demand mode.
+SKIP:
+{
+    if ( $ENV{CATALYST_SERVER} ) {
+        skip "Using remote server", 8;
+    }
+    
+    {
+        my $params;
+
+        my $request = POST(
+            'http://localhost/body/params',
+            'Content-Type' => 'application/x-www-form-urlencoded',
+            'Content'      => 'foo=bar&baz=quux'
+        );
+    
+        my $expected = { foo => 'bar', baz => 'quux' };
+
+        ok( my $response = request($request), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+
+        {
+            no strict 'refs';
+            ok(
+                eval '$params = ' . $response->content,
+                'Unserialize params'
+            );
+        }
+
+        is_deeply( $params, $expected, 'Catalyst::Request body parameters' );
+    }
+
+    # Test reading chunks of the request body using $c->read
+    {
+        my $creq;
+    
+        my $request = POST(
+            'http://localhost/body/read',
+            'Content-Type' => 'text/plain',
+            'Content'      => 'x' x 105_000
+        );
+    
+        my $expected = '10000|10000|10000|10000|10000|10000|10000|10000|10000|10000|5000';
+
+        ok( my $response = request($request), 'Request' );
+        ok( $response->is_success, 'Response Successful 2xx' );
+        is( $response->content_type, 'text/plain', 'Response Content-Type' );
+        is( $response->content, $expected, 'Response Content' );
+    }
+}
@@ -0,0 +1,45 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 13;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+use CGI::Simple::Cookie;
+use HTTP::Headers;
+use HTTP::Request::Common;
+use URI;
+
+{
+    my $creq;
+
+    my $request = GET( 'http://localhost/dump/request',
+        'Cookie' => 'Catalyst=Cool; Cool=Catalyst', );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like( $response->content, qr/'Catalyst::Request'/,
+        'Content is a serialized Catalyst::Request' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    isa_ok( $creq, 'Catalyst::Request' );
+    isa_ok( $creq->cookies->{Catalyst}, 'CGI::Simple::Cookie',
+            'Cookie Catalyst' );
+    is( $creq->cookies->{Catalyst}->name, 'Catalyst', 'Cookie Catalyst name' );
+    is( $creq->cookies->{Catalyst}->value, 'Cool', 'Cookie Catalyst value' );
+    isa_ok( $creq->cookies->{Cool}, 'CGI::Simple::Cookie', 'Cookie Cool' );
+    is( $creq->cookies->{Cool}->name,  'Cool',     'Cookie Cool name' );
+    is( $creq->cookies->{Cool}->value, 'Catalyst', 'Cookie Cool value' );
+
+    my $cookies = {
+        Catalyst => $creq->cookies->{Catalyst},
+        Cool     => $creq->cookies->{Cool}
+    };
+
+    is_deeply( $creq->cookies, $cookies, 'Cookies' );
+}
@@ -0,0 +1,71 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 17;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+use HTTP::Headers;
+use HTTP::Request::Common;
+
+{
+    my $creq;
+
+    my $request = GET( 'http://localhost/dump/request', 
+        'User-Agent'       => 'MyAgen/1.0',
+        'X-Whats-Cool'     => 'Catalyst',
+        'X-Multiple'       => [ 1 .. 5 ],
+        'X-Forwarded-Host' => 'frontend.server.com',
+        'X-Forwarded-For'  => '192.168.1.1, 1.2.3.4',
+    );
+ 
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like( $response->content, qr/^bless\( .* 'Catalyst::Request' \)$/s, 'Content is a serialized Catalyst::Request' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    isa_ok( $creq, 'Catalyst::Request' );
+    isa_ok( $creq->headers, 'HTTP::Headers', 'Catalyst::Request->headers' );
+    is( $creq->header('X-Whats-Cool'), $request->header('X-Whats-Cool'), 'Catalyst::Request->header X-Whats-Cool' );
+    
+    { # Test that multiple headers are joined as per RFC 2616 4.2 and RFC 3875 4.1.18
+
+        my $excpected = '1, 2, 3, 4, 5';
+        my $got       = $creq->header('X-Multiple'); # HTTP::Headers is context sensitive, "force" scalar context
+
+        is( $got, $excpected, 'Multiple message-headers are joined as a comma-separated list' );
+    }
+
+    is( $creq->header('User-Agent'), $request->header('User-Agent'), 'Catalyst::Request->header User-Agent' );
+
+    my $host = sprintf( '%s:%d', $request->uri->host, $request->uri->port );
+    is( $creq->header('Host'), $host, 'Catalyst::Request->header Host' );
+
+    SKIP:
+    {
+        if ( $ENV{CATALYST_SERVER} && $ENV{CATALYST_SERVER} !~ /127.0.0.1|localhost/ ) {
+            skip "Using remote server", 2;
+        }
+    
+        is( $creq->base->host, 'frontend.server.com', 'Catalyst::Request proxied base' );
+        is( $creq->address, '1.2.3.4', 'Catalyst::Request proxied address' );
+    }
+
+    SKIP:
+    {
+        if ( $ENV{CATALYST_SERVER} ) {
+            skip "Using remote server", 4;
+        }
+        # test that we can ignore the proxy support
+        TestApp->config->{ignore_frontend_proxy} = 1;
+        ok( $response = request($request), 'Request' );
+        ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+        is( $creq->base, 'http://localhost/', 'Catalyst::Request non-proxied base' );
+        is( $creq->address, '127.0.0.1', 'Catalyst::Request non-proxied address' );
+    }
+}
@@ -0,0 +1,129 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 35;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+use HTTP::Headers;
+use HTTP::Request::Common;
+
+{
+    my $creq;
+
+    my $parameters = { 'a' => [qw(A b C d E f G)], };
+
+    my $query = join( '&', map { 'a=' . $_ } @{ $parameters->{a} } );
+
+    ok( my $response = request("http://localhost/dump/request?$query"),
+        'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method, 'GET', 'Catalyst::Request method' );
+    is_deeply( $creq->{parameters}, $parameters,
+        'Catalyst::Request parameters' );
+}
+
+{
+    my $creq;
+    ok( my $response = request("http://localhost/dump/request?q=foo%2bbar"),
+        'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    ok( eval '$creq = ' . $response->content );
+    is $creq->{parameters}->{q}, 'foo+bar', '%2b not double decoded';
+}
+
+{
+    my $creq;
+
+    my $parameters = {
+        'a'     => [qw(A b C d E f G)],
+        '%'     => [ '%', '"', '& - &' ],
+        'blank' => '',
+    };
+
+    my $request = POST(
+        'http://localhost/dump/request/a/b?a=1&a=2&a=3',
+        'Content'      => $parameters,
+        'Content-Type' => 'application/x-www-form-urlencoded'
+    );
+
+    unshift( @{ $parameters->{a} }, 1, 2, 3 );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method, 'POST', 'Catalyst::Request method' );
+    is_deeply( $creq->{parameters}, $parameters,
+        'Catalyst::Request parameters' );
+    is_deeply( $creq->arguments, [qw(a b)], 'Catalyst::Request arguments' );
+    is_deeply( $creq->{uploads}, {}, 'Catalyst::Request uploads' );
+    is_deeply( $creq->cookies,   {}, 'Catalyst::Request cookie' );
+}
+
+# http://dev.catalyst.perl.org/ticket/37
+# multipart/form-data parameters that contain 'http://'
+# was an HTTP::Message bug, but HTTP::Body handles it properly now
+{
+    my $creq;
+
+    my $parameters = {
+        'url'   => 'http://www.google.com',
+        'blank' => '',
+    };
+
+    my $request = POST( 'http://localhost/dump/request',
+        'Content-Type' => 'multipart/form-data',
+        'Content'      => $parameters,
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is_deeply( $creq->{parameters}, $parameters, 'Catalyst::Request parameters' );
+}
+
+# raw query string support
+{
+    my $creq;
+    
+    my $parameters = {
+        a     => 1,
+        blank => '',
+    };
+
+    my $request = POST(
+        'http://localhost/dump/request/a/b?query+string',
+        'Content'      => $parameters,
+        'Content-Type' => 'application/x-www-form-urlencoded'
+    );
+    
+    ok( my $response = request($request), 'Request' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->{uri}->query, 'query+string', 'Catalyst::Request POST query_string' );
+    is( $creq->query_keywords, 'query string', 'Catalyst::Request query_keywords' );
+    is_deeply( $creq->{parameters}, $parameters, 'Catalyst::Request parameters' );
+    
+    ok( $response = request('http://localhost/dump/request/a/b?x=1&y=1&z=1'), 'Request' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->{uri}->query, 'x=1&y=1&z=1', 'Catalyst::Request GET query_string' );
+}
@@ -0,0 +1,247 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More;
+use Catalyst::Test 'TestApp';
+
+use Catalyst::Request;
+use Catalyst::Request::Upload;
+use HTTP::Headers;
+use HTTP::Headers::Util 'split_header_words';
+use HTTP::Request::Common;
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/dump/request/',
+        'Content-Type' => 'form-data',
+        'Content'      => [
+            'live_engine_request_cookies.t' =>
+              ["$FindBin::Bin/live_engine_request_cookies.t"],
+            'live_engine_request_headers.t' =>
+              ["$FindBin::Bin/live_engine_request_headers.t"],
+            'live_engine_request_uploads.t' =>
+              ["$FindBin::Bin/live_engine_request_uploads.t"],
+        ]
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+
+    {
+        no strict 'refs';
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+    }
+
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method, 'POST', 'Catalyst::Request method' );
+    is( $creq->content_type, 'multipart/form-data',
+        'Catalyst::Request Content-Type' );
+    is( $creq->content_length, $request->content_length,
+        'Catalyst::Request Content-Length' );
+
+    for my $part ( $request->parts ) {
+
+        my $disposition = $part->header('Content-Disposition');
+        my %parameters  = @{ ( split_header_words($disposition) )[0] };
+
+        my $upload = $creq->{uploads}->{ $parameters{filename} };
+
+        isa_ok( $upload, 'Catalyst::Request::Upload' );
+
+        is( $upload->type, $part->content_type, 'Upload Content-Type' );
+        is( $upload->size, length( $part->content ), 'Upload Content-Length' );
+
+        # make sure upload is accessible via legacy params->{$file}
+        is( $creq->{parameters}->{ $upload->filename },
+            $upload->filename, 'legacy param method ok' );
+
+        ok( !-e $upload->tempname, 'Upload temp file was deleted' );
+    }
+}
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/dump/request/',
+        'Content-Type' => 'multipart/form-data',
+        'Content'      => [
+            'testfile' => ["$FindBin::Bin/live_engine_request_cookies.t"],
+            'testfile' => ["$FindBin::Bin/live_engine_request_headers.t"],
+            'testfile' => ["$FindBin::Bin/live_engine_request_uploads.t"],
+        ]
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+
+    {
+        no strict 'refs';
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+    }
+
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method, 'POST', 'Catalyst::Request method' );
+    is( $creq->content_type, 'multipart/form-data',
+        'Catalyst::Request Content-Type' );
+    is( $creq->content_length, $request->content_length,
+        'Catalyst::Request Content-Length' );
+
+    my @parts = $request->parts;
+
+    for ( my $i = 0 ; $i < @parts ; $i++ ) {
+
+        my $part        = $parts[$i];
+        my $disposition = $part->header('Content-Disposition');
+        my %parameters  = @{ ( split_header_words($disposition) )[0] };
+
+        my $upload = $creq->{uploads}->{ $parameters{name} }->[$i];
+
+        isa_ok( $upload, 'Catalyst::Request::Upload' );
+        is( $upload->type, $part->content_type, 'Upload Content-Type' );
+        is( $upload->filename, $parameters{filename}, 'Upload filename' );
+        is( $upload->size, length( $part->content ), 'Upload Content-Length' );
+
+        ok( !-e $upload->tempname, 'Upload temp file was deleted' );
+    }
+}
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/engine/request/uploads/slurp',
+        'Content-Type' => 'multipart/form-data',
+        'Content'      =>
+          [ 'slurp' => ["$FindBin::Bin/live_engine_request_uploads.t"], ]
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->content, ( $request->parts )[0]->content, 'Content' );
+}
+
+{
+    my $request = POST(
+        'http://localhost/dump/request',
+        'Content-Type' => 'multipart/form-data',
+        'Content'      =>
+          [ 'file' => ["$FindBin::Bin/../catalyst_130pix.gif"], ]
+    );
+
+    # LWP will auto-correct Content-Length when using a remote server
+    SKIP:
+    {
+        if ( $ENV{CATALYST_SERVER} ) {
+            skip 'Using remote server', 2;
+        }
+
+        # Sending wrong Content-Length here and see if subequent requests fail
+        $request->header('Content-Length' => $request->header('Content-Length') + 1);
+
+        ok( my $response = request($request), 'Request' );
+        ok( !$response->is_success, 'Response Error' );
+    }
+
+    $request = POST(
+        'http://localhost/dump/request',
+        'Content-Type' => 'multipart/form-data',
+        'Content'      =>
+          [ 'file1' => ["$FindBin::Bin/../catalyst_130pix.gif"],
+            'file2' => ["$FindBin::Bin/../catalyst_130pix.gif"], ]
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like( $response->content, qr/file1 => bless/, 'Upload with name file1');
+    like( $response->content, qr/file2 => bless/, 'Upload with name file2');
+}
+
+{
+    my $creq;
+
+    my $request = POST(
+        'http://localhost/dump/request/',
+        'Content-Type' => 'form-data',
+        'Content'      => [
+            'testfile' => 'textfield value',
+            'testfile' => ["$FindBin::Bin/../catalyst_130pix.gif"],
+        ]
+    );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    like(
+        $response->content,
+        qr/^bless\( .* 'Catalyst::Request' \)$/s,
+        'Content is a serialized Catalyst::Request'
+    );
+
+    {
+        no strict 'refs';
+        ok(
+            eval '$creq = ' . $response->content,
+            'Unserialize Catalyst::Request'
+        );
+    }
+
+    isa_ok( $creq, 'Catalyst::Request' );
+    is( $creq->method, 'POST', 'Catalyst::Request method' );
+    is( $creq->content_type, 'multipart/form-data',
+        'Catalyst::Request Content-Type' );
+    is( $creq->content_length, $request->content_length,
+        'Catalyst::Request Content-Length' );
+
+    my $param = $creq->{parameters}->{testfile};
+
+    ok( @$param == 2, '2 values' );
+    is( $param->[0], 'textfield value', 'correct value' );
+    like( $param->[1], qr/\Qcatalyst_130pix.gif/, 'filename' );
+
+    for my $part ( $request->parts ) {
+
+        my $disposition = $part->header('Content-Disposition');
+        my %parameters  = @{ ( split_header_words($disposition) )[0] };
+
+        next unless exists $parameters{filename};
+
+        my $upload = $creq->{uploads}->{ $parameters{name} };
+
+        isa_ok( $upload, 'Catalyst::Request::Upload' );
+
+        is( $upload->type, $part->content_type, 'Upload Content-Type' );
+        is( $upload->size, length( $part->content ), 'Upload Content-Length' );
+        is( $upload->filename, 'catalyst_130pix.gif' );
+    }
+}
+
+done_testing;
+
@@ -0,0 +1,121 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 49;
+use Catalyst::Test 'TestApp';
+use Catalyst::Request;
+
+my $creq;
+
+# test that the path can be changed
+{
+    ok( my $response = request('http://localhost/engine/request/uri/change_path'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    like( $creq->uri, qr{/my/app/lives/here$}, 'URI contains new path' );
+}
+
+# test that path properly removes the base location
+{
+    ok( my $response = request('http://localhost/engine/request/uri/change_base'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    like( $creq->base, qr{/new/location}, 'Base URI contains new location' );
+    is( $creq->path, 'engine/request/uri/change_base', 'URI contains correct path' );
+}
+
+# test that base + path is correct
+{
+    ok( my $response = request('http://localhost/engine/request/uri'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->base . $creq->path, $creq->uri, 'Base + Path ok' );
+}
+
+# test base is correct for HTTPS URLs
+SKIP:
+{
+    if ( $ENV{CATALYST_SERVER} ) {
+        skip 'Using remote server', 5;
+    }
+    
+    local $ENV{HTTPS} = 'on';
+    ok( my $response = request('https://localhost/engine/request/uri'), 'HTTPS Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->base, 'https://localhost/', 'HTTPS base ok' );
+    is( $creq->uri, 'https://localhost/engine/request/uri', 'HTTPS uri ok' );
+}
+
+# test that we can use semi-colons as separators
+{
+    my $parameters = {
+        a => [ qw/1 2/ ],
+        b => 3,
+    };
+    
+    ok( my $response = request('http://localhost/engine/request/uri?a=1;a=2;b=3'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->{uri}->query, 'a=1;a=2;b=3', 'Query string ok' );
+    is_deeply( $creq->{parameters}, $parameters, 'Parameters ok' );
+}
+
+# test that query params are unescaped properly
+{
+    ok( my $response = request('http://localhost/engine/request/uri?text=Catalyst%20Rocks'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
+    is( $creq->{uri}->query, 'text=Catalyst%20Rocks', 'Query string ok' );
+    is( $creq->{parameters}->{text}, 'Catalyst Rocks', 'Unescaped param ok' );
+}
+
+# test that uri_with adds params
+{
+    ok( my $response = request('http://localhost/engine/request/uri/uri_with'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( !defined $response->header( 'X-Catalyst-Param-a' ), 'param "a" ok' );
+    is( $response->header( 'X-Catalyst-Param-b' ), '1', 'param "b" ok' );
+}
+
+# test that uri_with adds params (and preserves)
+{
+    ok( my $response = request('http://localhost/engine/request/uri/uri_with?a=1'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->header( 'X-Catalyst-Param-a' ), '1', 'param "a" ok' );
+    is( $response->header( 'X-Catalyst-Param-b' ), '1', 'param "b" ok' );
+}
+
+# test that uri_with replaces params (and preserves)
+{
+    ok( my $response = request('http://localhost/engine/request/uri/uri_with?a=1&b=2'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->header( 'X-Catalyst-Param-a' ), '1', 'param "a" ok' );
+    is( $response->header( 'X-Catalyst-Param-b' ), '1', 'param "b" ok' );
+}
+
+# test that uri_with replaces params (and preserves)
+{
+    ok( my $response = request('http://localhost/engine/request/uri/uri_with_object'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    like( $response->header( 'X-Catalyst-Param-a' ), qr(https?://localhost[^/]*/), 'param "a" ok' );
+}
+
+# test that uri_with is utf8 safe
+{
+    ok( my $response = request("http://localhost/engine/request/uri/uri_with_utf8"), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    like( $response->header( 'X-Catalyst-uri-with' ), qr/%E2%98%A0$/, 'uri_with ok' );
+}
+
+# test with undef -- no warnings should be thrown
+{
+    ok( my $response = request("http://localhost/engine/request/uri/uri_with_undef"), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->header( 'X-Catalyst-warnings' ), 0, 'no warnings emitted' );
+}
@@ -0,0 +1,73 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 15;
+use Catalyst::Test 'TestApp';
+use HTTP::Headers::Util 'split_header_words';
+
+my $expected = {
+    catalyst => [qw|catalyst cool path /bah|],
+    cool     => [qw|cool catalyst path /|]
+};
+
+{
+    ok( my $response = request('http://localhost/engine/response/cookies/one'),
+        'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/cookies/one', 'Test Action' );
+
+    my $cookies = {};
+
+    for my $string ( $response->header('Set-Cookie') ) {
+        my $cookie = [ split_header_words $string];
+        $cookies->{ $cookie->[0]->[0] } = $cookie->[0];
+    }
+
+    is_deeply( $cookies, $expected, 'Response Cookies' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/cookies/two'),
+        'Request' );
+    ok( $response->is_redirect, 'Response Redirection 3xx' );
+    is( $response->code, 302, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/cookies/two', 'Test Action' );
+
+    my $cookies = {};
+
+    for my $string ( $response->header('Set-Cookie') ) {
+        my $cookie = [ split_header_words $string];
+        $cookies->{ $cookie->[0]->[0] } = $cookie->[0];
+    }
+
+    is_deeply( $cookies, $expected, 'Response Cookies' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/cookies/three'),
+        'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/cookies/three', 'Test Action' );
+
+    my $cookies = {};
+
+    for my $string ( $response->header('Set-Cookie') ) {
+        my $cookie = [ split_header_words $string];
+        $cookies->{ $cookie->[0]->[0] } = $cookie->[0];
+    }
+
+    is_deeply( $cookies, {
+        hash => [ qw(hash a&b&c path /) ],
+        this_is_the_real_name => [ qw(this_is_the_real_name foo&bar path /) ], # not "object"
+    }, 'Response Cookies' );
+}
@@ -0,0 +1,60 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 18;
+use Catalyst::Test 'TestApp';
+
+close STDERR;    # i'm naughty :)
+
+{
+    ok( my $response = request('http://localhost/engine/response/errors/one'),
+        'Request' );
+    ok( $response->is_error, 'Response Server Error 5xx' );
+    is( $response->code,         500,         'Response Code' );
+    is( $response->content_type, 'text/html', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/errors/one', 'Test Action' );
+    like(
+        $response->header('X-Catalyst-Error'),
+        qr/^Caught exception/,
+        'Catalyst Error'
+    );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/errors/two'),
+        'Request' );
+    ok( $response->is_error, 'Response Server Error 5xx' );
+    is( $response->code,         500,         'Response Code' );
+    is( $response->content_type, 'text/html', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/errors/two', 'Test Action' );
+    like(
+        $response->header('X-Catalyst-Error'),
+        qr/^Couldn't forward to/,
+        'Catalyst Error'
+    );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/errors/three'),
+        'Request' );
+    ok( $response->is_error, 'Response Server Error 5xx' );
+    is( $response->code,         500,         'Response Code' );
+    is( $response->content_type, 'text/html', 'Response Content-Type' );
+    is(
+        $response->header('X-Catalyst-Action'),
+        'engine/response/errors/three',
+        'Test Action'
+    );
+    like(
+        $response->header('X-Catalyst-Error'),
+        qr/I'm going to die!/,
+        'Catalyst Error'
+    );
+}
@@ -0,0 +1,58 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 18;
+use Catalyst::Test 'TestApp';
+use HTTP::Request::Common;
+
+my $content_length;
+
+foreach my $method qw(HEAD GET) {
+    my $expected = join( ', ', 1 .. 10 );
+
+    my $request = HTTP::Request::Common->can($method)
+        ->( 'http://localhost/engine/response/headers/one' );
+
+    ok( my $response = request($request), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->code, 200, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'),
+        'engine/response/headers/one', 'Test Action' );
+    is( $response->header('X-Header-Catalyst'),
+        'Cool', 'Response Header X-Header-Catalyst' );
+    is( $response->header('X-Header-Cool'),
+        'Catalyst', 'Response Header X-Header-Cool' );
+    is( $response->header('X-Header-Numbers'),
+        $expected, 'Response Header X-Header-Numbers' );
+
+    use bytes;
+    if ( $method eq 'HEAD' ) {
+        $content_length = $response->header('Content-Length');
+        ok( $content_length > 0, 'Response Header Content-Length' );
+        is( length($response->content),
+            0,
+            'HEAD method content is empty' );
+    }
+    elsif ( $method eq 'GET' ) {
+        # method name is echo'd back in content-body, which
+        # accounts for difference in content length.  In normal
+        # cases the Content-Length should be the same regardless
+        # of if its a GET or HEAD request.
+        SKIP:
+        {
+            if ( $ENV{CATALYST_SERVER} ) {
+                skip "Using remote server", 2;
+            }
+            is( $response->header('Content-Length'),
+                $content_length - 1, 'Response Header Content-Length' );
+            is( length($response->content),
+                $response->header('Content-Length'),
+                'GET method content' );
+        }
+    }
+}
@@ -0,0 +1,27 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 6;
+use Catalyst::Test 'TestApp';
+
+# phaylon noticed that refactored was truncating output on large images.
+# This test tests 100K and 1M output content.
+
+my $expected = {
+    one => 'x' x (100 * 1024),
+    two => 'y' x (1024 * 1024),
+};
+
+for my $action ( keys %{$expected} ) {
+    ok( my $response = request('http://localhost/engine/response/large/' . $action ),
+        'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    
+    is( length( $response->content ), length( $expected->{$action} ), 'Length OK' );
+}
+
@@ -0,0 +1,48 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 26;
+use Catalyst::Test 'TestApp';
+
+{
+    ok( my $response = request('http://localhost/engine/response/redirect/one'), 'Request' );
+    ok( $response->is_redirect, 'Response Redirection 3xx' );
+    is( $response->code, 302, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/one', 'Test Action' );
+    is( $response->header('Location'), '/test/writing/is/boring', 'Response Header Location' );
+    ok( $response->header('Content-Length'), '302 Redirect contains Content-Length' );
+    ok( $response->content, '302 Redirect contains a response body' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/redirect/two'), 'Request' );
+    ok( $response->is_redirect, 'Response Redirection 3xx' );
+    is( $response->code, 302, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/two', 'Test Action' );
+    is( $response->header('Location'), 'http://www.google.com/', 'Response Header Location' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/redirect/three'), 'Request' );
+    ok( $response->is_redirect, 'Response Redirection 3xx' );
+    is( $response->code, 301, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/three', 'Test Action' );
+    is( $response->header('Location'), 'http://www.google.com/', 'Response Header Location' );
+    ok( $response->header('Content-Length'), '301 Redirect contains Content-Length' );
+    ok( $response->content, '301 Redirect contains a response body' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/redirect/four'), 'Request' );
+    ok( $response->is_redirect, 'Response Redirection 3xx' );
+    is( $response->code, 307, 'Response Code' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/four', 'Test Action' );
+    is( $response->header('Location'), 'http://www.google.com/', 'Response Header Location' );
+    ok( $response->header('Content-Length'), '307 Redirect contains Content-Length' );
+    ok( $response->content, '307 Redirect contains a response body' );
+}
@@ -0,0 +1,55 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 30;
+use Catalyst::Test 'TestApp';
+
+{
+    ok( my $response = request('http://localhost/engine/response/status/s200'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    is( $response->code, 200, 'Response Code' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s200', 'Test Action' );
+    like( $response->content, qr/^200/, 'Response Content' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/status/s400'), 'Request' );
+    ok( $response->is_error, 'Response Client Error 4xx' );
+    is( $response->code, 400, 'Response Code' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s400', 'Test Action' );
+    like( $response->content, qr/^400/, 'Response Content' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/status/s403'), 'Request' );
+    ok( $response->is_error, 'Response Client Error 4xx' );
+    is( $response->code, 403, 'Response Code' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s403', 'Test Action' );
+    like( $response->content, qr/^403/, 'Response Content' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/status/s404'), 'Request' );
+    ok( $response->is_error, 'Response Client Error 4xx' );
+    is( $response->code, 404, 'Response Code' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s404', 'Test Action' );
+    like( $response->content, qr/^404/, 'Response Content' );
+}
+
+{
+    ok( my $response = request('http://localhost/engine/response/status/s500'), 'Request' );
+    ok( $response->is_error, 'Response Server Error 5xx' );
+    is( $response->code, 500, 'Response Code' );
+    is( $response->content_type, 'text/plain', 'Response Content-Type' );
+    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s500', 'Test Action' );
+    like( $response->content, qr/^500/, 'Response Content' );
+}
@@ -0,0 +1,19 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 1;
+use Catalyst::Test 'TestApp';
+
+SKIP:
+{
+    if ( $ENV{CATALYST_SERVER} ) {
+        skip "Using remote server", 1;
+    }
+    # Allow overriding automatic root.
+    is( TestApp->config->{root}, '/some/dir' );
+}
@@ -0,0 +1,16 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 2;
+use Catalyst::Test 'TestApp';
+
+{
+  # Allow overriding automatic root.
+    ok( my $response = request('http://localhost/engine/response/headers/one'), 'Request' );
+    is( $response->header('X-Catalyst-Plugin-Setup'), '1' );
+}
@@ -0,0 +1,60 @@
+#!/usr/bin/perl
+# live_fork.t 
+# Copyright (c) 2006 Jonathan Rockway <jrockway@cpan.org>
+
+=head1 SYNOPSIS
+
+Tests if Catalyst can fork/exec other processes successfully
+
+=cut
+use strict;
+use warnings;
+use Test::More;
+use YAML;
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+use Catalyst::Test qw(TestApp);
+
+plan skip_all => 'Using remote server'
+    if $ENV{CATALYST_SERVER};
+    
+plan skip_all => 'Skipping fork tests: no /bin/ls'
+    if !-e '/bin/ls'; # see if /bin/ls exists
+    
+plan tests => 13; # otherwise
+
+{
+  system:
+    ok(my $result = get('/fork/system/%2Fbin%2Fls'), 'system');
+    my @result = split /$/m, $result;
+    $result = join q{}, @result[-4..-1];
+    
+    my $result_ref = eval { Load($result) };
+    ok($result_ref, 'is YAML');
+    is($result_ref->{result}, 0, 'exited OK');
+}
+
+{ 
+  backticks:
+    ok(my $result = get('/fork/backticks/%2Fbin%2Fls'), '`backticks`');
+    my @result = split /$/m, $result;
+    $result = join q{}, @result[-4..-1];
+    
+    my $result_ref = eval { Load($result) };
+    ok($result_ref, 'is YAML');
+    is($result_ref->{code}, 0, 'exited successfully');
+    like($result_ref->{result}, qr{^/bin/ls[^:]}, 'contains ^/bin/ls$');
+    like($result_ref->{result}, qr{\n.*\n}m, 'contains two newlines');
+}
+{ 
+  fork:
+    ok(my $result = get('/fork/fork'), 'fork');
+    my @result = split /$/m, $result;
+    $result = join q{}, @result[-4..-1];
+    
+    my $result_ref = eval { Load($result) };
+    ok($result_ref, 'is YAML');
+    isnt($result_ref->{pid}, 0, q{fork's "pid" wasn't 0});
+    isnt($result_ref->{pid}, $$, 'fork got a new pid');
+    is($result_ref->{result}, 'ok', 'fork was effective');
+}
@@ -0,0 +1,23 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 3;
+use Catalyst::Test 'TestApp';
+
+SKIP:
+{
+    # Net::HTTP::Methods crashes when talking to a remote server because this
+    # test causes a very long header line to be sent
+    if ( $ENV{CATALYST_SERVER} ) {
+        skip 'Using remote server', 3;
+    }
+
+    ok( my $response = request('http://localhost/loop_test'), 'Request' );
+    ok( $response->is_success, 'Response Successful 2xx' );
+    ok( $response->header('X-Class-Forward-Test-Method'), 'Loop OK' );
+}
@@ -0,0 +1,23 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 5;
+use Catalyst::Test 'TestApp';
+
+my @expected = qw[
+    Catalyst::Plugin::Test::Errors Catalyst::Plugin::Test::Headers Catalyst::Plugin::Test::Inline Catalyst::Plugin::Test::MangleDollarUnderScore Catalyst::Plugin::Test::Plugin TestApp::Plugin::AddDispatchTypes TestApp::Plugin::FullyQualified
+];
+
+my $expected = join( ", ", @expected );
+
+ok( my $response = request('http://localhost/dump/request'), 'Request' );
+ok( $response->is_success, 'Response Successful 2xx' );
+is( $response->content_type, 'text/plain', 'Response Content-Type' );
+like( $response->content, qr/'Catalyst::Request'/,
+    'Content is a serialized Catalyst::Request' );
+is( $response->header('X-Catalyst-Plugins'), $expected, 'Loaded plugins' );
@@ -0,0 +1,81 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 28;
+use Catalyst::Test 'TestApp';
+use Data::Dumper;
+
+local $^W = 0;
+
+my $uri_base = 'http://localhost/priorities';
+my @tests = (
+
+    #   Simple
+    'Regex vs. Local',      { path => '/re_vs_loc',      expect => 'local' },
+    'Regex vs. LocalRegex', { path => '/re_vs_locre',    expect => 'regex' },
+    'Regex vs. Path',       { path => '/re_vs_path',     expect => 'path' },
+    'Local vs. LocalRegex', { path => '/loc_vs_locre',   expect => 'local' },
+    'Local vs. Path 1',     { path => '/loc_vs_path1',   expect => 'local' },
+    'Local vs. Path 2',     { path => '/loc_vs_path2',   expect => 'path' },
+    'Path  vs. LocalRegex', { path => '/path_vs_locre',  expect => 'path' },
+
+    #   index
+    'index vs. Regex',      { path => '/re_vs_index',    expect => 'index' },
+    'index vs. Local',      { path => '/loc_vs_index',   expect => 'index' },
+    'index vs. LocalRegex', { path => '/locre_vs_index', expect => 'index' },
+    'index vs. Path',       { path => '/path_vs_index',  expect => 'index' },
+
+    'multimethod zero',     { path => '/multimethod',    expect => 'zero' },
+    'multimethod one',      { path => '/multimethod/1',  expect => 'one 1' },
+    'multimethod two',      { path => '/multimethod/1/2',
+                                                         expect => 'two 1 2' },
+);
+
+while ( @tests ) {
+
+    my $name = shift @tests;
+    my $data = shift @tests;
+
+    #   Run tests for path with trailing slash and without
+  SKIP: for my $req_uri 
+    ( 
+        join( '' => $uri_base, $data->{ path } ),      # Without trailing path
+        join( '' => $uri_base, $data->{ path }, '/' ), # With trailing path
+    ) {
+        my $end_slash = ( $req_uri =~ qr(/$) ? 1 : 0 );
+
+        #   use slash_expect argument if URI ends with slash 
+        #   and the slash_expect argument is defined
+        my $expect = $data->{ expect } || '';
+        if ( $end_slash and exists $data->{ slash_expect } ) {
+            $expect = $data->{ slash_expect };
+        }
+
+        #   Call the URI on the TestApp
+        my $response = request( $req_uri );
+
+        #   Leave expect out to see the result
+        unless ( $expect ) {
+            skip 'Nothing expected, winner is ' . $response->content, 1;
+        }
+
+        #   Show error if response was no success
+        if ( not $response->is_success ) {
+            diag 'Error: ' . $response->headers->{ 'x-catalyst-error' };
+        }
+
+        #   Test if content matches expectations.
+        #   TODO This might flood the screen with the catalyst please-come-later
+        #        page. So I don't know it is a good idea.
+        is( $response->content, $expect,
+            "$name: @{[ $data->{ expect } ]} wins"
+            . ( $end_slash ? ' (trailing slash)' : '' )
+        );
+    }
+}
+
@@ -0,0 +1,25 @@
+#!perl
+
+use strict;
+use warnings;
+
+use FindBin;
+use lib "$FindBin::Bin/../lib";
+
+use Test::More tests => 3;
+use Catalyst::Test 'TestApp';
+
+local $^W = 0;
+
+SKIP:
+{
+    # Net::HTTP::Methods crashes when talking to a remote server because this
+    # test causes a very long header line to be sent
+    if ( $ENV{CATALYST_SERVER} ) {
+        skip 'Using remote server', 3;
+    }
+
+    ok( my $response = request('http://localhost/recursion_test'), 'Request' );
+    ok( !$response->is_success, 'Response Not Successful' );
+    is( $response->header('X-Catalyst-Error'), 'Deep recursion detected calling "/recursion_test"', 'Deep Recursion Detected' );
+}
@@ -0,0 +1,10 @@
+use strict;
+use warnings;
+
+use File::Spec;
+use FindBin ();
+use Test::More;
+use Test::NoTabs;
+
+all_perl_files_ok(qw/lib/);
+
@@ -0,0 +1,8 @@
+use strict;
+use warnings;
+use Test::More;
+
+use Test::Pod 1.14;
+
+all_pod_files_ok();
+
@@ -0,0 +1,16 @@
+use strict;
+use warnings;
+use Test::More;
+
+use Pod::Coverage 0.19;
+use Test::Pod::Coverage 1.04;
+
+my @modules = all_modules;
+our @private = ( 'BUILD' );
+foreach my $module (@modules) {
+    local @private = (@private, 'run') if $module =~ /^Catalyst::Script::/;
+    pod_coverage_ok($module, { also_private => \@private });
+}
+
+done_testing;
+
@@ -0,0 +1,18 @@
+package ACLTestApp::Controller::Root;
+use Test::More;
+
+use base 'Catalyst::Controller';
+
+__PACKAGE__->config->{namespace} = '';
+
+sub foobar : Private {
+    die $Catalyst::DETACH;
+}
+
+sub gorch : Local {
+    my ( $self, $c, $frozjob ) = @_;
+    is $frozjob, 'wozzle';
+    $c->res->body("gorch");
+}
+
+1;
@@ -0,0 +1,26 @@
+package ACLTestApp;
+use Test::More;
+
+use strict;
+use warnings;
+use MRO::Compat;
+use Scalar::Util ();
+
+use base qw/Catalyst Catalyst::Controller/;
+use Catalyst qw//;
+
+sub execute {
+    my $c = shift;
+    my ( $class, $action ) = @_;
+
+    if ( Scalar::Util::blessed($action)
+	 and $action->name ne "foobar" ) {
+	eval { $c->detach( 'foobar', [$action, 'foo'] ) };
+    }
+
+    $c->next::method( @_ );
+}
+
+__PACKAGE__->setup;
+
+1;
@@ -0,0 +1,42 @@
+package CDICompatTestPlugin;
+
+# This plugin specificially tests an edge case of C::D::I compat,
+# where you load a plugin which creates an accessor with the same
+# name as a class data accessor (_config in this case)..
+
+# This is what happens if you use the authentication back-compat
+# stuff, as C::A::Plugin::Credential::Password is added to the plugin
+# list, and that uses base C::A::C::P class, does the mk_accessors.
+
+# If a class data method called _config hasn't been created in 
+# MyApp ($app below), then our call to ->config gets our accessor
+# (rather than the class data one), and we fail..
+
+use strict;
+use warnings;
+use base qw/Class::Accessor::Fast/;
+use MRO::Compat;
+__PACKAGE__->mk_accessors(qw/_config/);
+
+sub setup {
+    my $app = shift;
+
+    $app->config;
+    $app->next::method(@_);
+}
+
+# However, if we are too enthusiastic about adding accessors to the
+# MyApp package, then this method isn't called (as there is a local 
+# symbol already).
+
+# Note - use a different package here, so that Moose's 
+# package detection code doesn't get confused..
+$CDICompatTestPlugin::Data::HAS_RUN_SETUP_FINISHED = 0;
+
+sub setup_finished {
+    my $app = shift;
+    $CDICompatTestPlugin::Data::HAS_RUN_SETUP_FINISHED = 1;
+    $app->next::method(@_);
+}
+
+1;
@@ -8,7 +8,7 @@ use base qw/Catalyst::Action/;
 sub execute {
     my $self = shift;
     my ( $controller, $c ) = @_;
-    $self->NEXT::execute( @_ );
+    $self->next::method( @_ );
     $c->res->header( 'X-Action-After', $c->stash->{after_message} );
 }
 
@@ -9,7 +9,7 @@ sub execute {
     my $self = shift;
     my ( $controller, $c ) = @_;
     $c->stash->{test} = 'works';
-    $self->NEXT::execute( @_ );
+    $self->next::method( @_ );
 }
 
 1;
@@ -0,0 +1,17 @@
+package Catalyst::Plugin::Test::Deprecated;
+
+use strict;
+use warnings;
+
+sub prepare {
+    my $class = shift;
+    # Note: This use of NEXT is deliberately left here (without a use NEXT)
+    #       to ensure back compat, as NEXT always used to be loaded, but
+    #       is now replaced by Class::C3::Adopt::NEXT.
+    my $c = $class->NEXT::prepare(@_);
+    $c->response->header( 'X-Catalyst-Plugin-Deprecated' => 1 );
+
+    return $c;
+}
+
+1;
@@ -1,12 +1,13 @@
 package Catalyst::Plugin::Test::Errors;
 
 use strict;
+use MRO::Compat;
 
 sub error {
     my $c = shift;
 
     unless ( $_[0] ) {
-        return $c->NEXT::error(@_);
+        return $c->next::method(@_);
     }
 
     if ( $_[0] =~ /^(Unknown resource|No default action defined)/ ) {
@@ -26,7 +27,7 @@ sub error {
 
     $c->response->headers->push_header( 'X-Catalyst-Error' => $error );
 
-    $c->NEXT::error(@_);
+    $c->next::method(@_);
 }
 
 1;
@@ -1,11 +1,12 @@
 package Catalyst::Plugin::Test::Headers;
 
 use strict;
+use MRO::Compat;
 
 sub prepare {
     my $class = shift;
 
-    my $c = $class->NEXT::prepare(@_);
+    my $c = $class->next::method(@_);
 
     $c->response->header( 'X-Catalyst-Engine' => $c->engine );
     $c->response->header( 'X-Catalyst-Debug' => $c->debug ? 1 : 0 );
@@ -26,7 +27,7 @@ sub prepare {
 
 sub prepare_action {
     my $c = shift;
-    $c->NEXT::prepare_action(@_);
+    $c->next::method(@_);
     $c->res->header( 'X-Catalyst-Action' => $c->req->action );
 }
 
@@ -0,0 +1,16 @@
+package Catalyst::Plugin::Test::MangleDollarUnderScore;
+use strict;
+use warnings;
+
+our $VERSION = 0.1; # Make is_class_loaded happy
+
+# Class::MOP::load_class($_) can hurt you real hard.
+BEGIN { $_ = q{
+mst sayeth, Class::MOP::load_class($_) will ruin your life
+rafl spokeh "i ♥ my $_"',
+and verrily forsooth, t0m made tests
+and yea, there was fail' }; }
+
+1;
+__END__
+
@@ -1,8 +1,10 @@
 package Catalyst::Plugin::Test::Plugin;
 
 use strict;
+use warnings;
+use MRO::Compat;
 
-use base qw/Catalyst::Base Class::Data::Inheritable/;
+use base qw/Class::Data::Inheritable/;
 
  __PACKAGE__->mk_classdata('ran_setup');
 
@@ -11,19 +13,23 @@ sub setup {
    $c->ran_setup('1');
 }
 
-sub  prepare {
-
+sub prepare {
     my $class = shift;
 
-    my $c = $class->NEXT::prepare(@_);
+    my $c = $class->next::method(@_);
     $c->response->header( 'X-Catalyst-Plugin-Setup' => $c->ran_setup );
 
     return $c;
-
 }
 
-sub end : Private {
-    my ($self,$c) = @_;
+# Note: Catalyst::Plugin::Server forces the body to
+#       be parsed, by calling the $c->req->body method in prepare_action.
+#       We need to test this, as this was broken by 5.80. See also
+#       t/aggregate/live_engine_request_body.t.
+sub prepare_action {
+    my $c = shift;
+    $c->res->header('X-Have-Request-Body', 1) if $c->req->body;
+    $c->next::method(@_);
 }
 
 1;
@@ -0,0 +1,9 @@
+package Catalyst::Script::Bar;
+use Moose;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+1;
@@ -0,0 +1,16 @@
+package Catalyst::Script::Baz;
+use Moose;
+use namespace::autoclean;
+
+use Test::More;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+after new_with_options => sub {
+    my ($self, %args) = @_;
+    is_deeply \%args, { application_name => 'ScriptTestApp' }, 'App name correct';
+};
+
+1;
@@ -0,0 +1,16 @@
+package Catalyst::Script::CompileTest;
+use Moose;
+use namespace::autoclean;
+
+use Test::More;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+after new_with_options => sub {
+    my ($self, %args) = @_;
+    is_deeply \%args, { application_name => 'ScriptTestApp' }, 'App name correct';
+};
+
+1;
@@ -0,0 +1,63 @@
+package ChainedActionsApp::Controller::Root;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller' }
+
+#
+# Sets the actions in this controller to be registered with no prefix
+# so they function identically to actions created in MyApp.pm
+#
+__PACKAGE__->config(namespace => '');
+
+sub setup : Chained('/') PathPart('') CaptureArgs(0) {
+    my ( $self, $c ) = @_;
+    # Common things here are to check for ACL and setup global contexts
+}
+
+sub home : Chained('setup') PathPart('') Args(0) {
+    my($self,$c) = @_;
+    $c->response->body( "Application Home Page" );
+}
+
+sub home_base : Chained('setup') PathPart('') CaptureArgs(2) {
+    my($self,$c,$proj_id,$title) = @_;
+    $c->stash({project_id=>$proj_id, project_title=>$title});
+}
+
+sub hpages : Chained('home_base') PathPart('') Args(0) {
+    my($self,$c) = @_;
+    $c->response->body( "List project " . $c->stash->{project_title} . " pages");
+}
+
+sub hpage : Chained('home_base') PathPart('') Args(2) {
+    my($self,$c,$page_id, $pagetitle) = @_;
+    $c->response->body( "This is $pagetitle page of " . $c->stash->{project_title} . " project" );
+}
+
+sub no_account : Chained('setup') PathPart('account') Args(0) {
+    my($self,$c) = @_;
+    $c->response->body( "New account o login" );
+}
+
+sub account_base : Chained('setup') PathPart('account') CaptureArgs(1) {
+    my($self,$c,$acc_id) = @_;
+    $c->stash({account_id=>$acc_id});
+}
+
+sub account : Chained('account_base') PathPart('') Args(0) {
+    my($self,$c,$acc) = @_;
+    $c->response->body( "This is account " . $c->stash->{account_id} );
+}
+
+sub default : Chained('setup') PathPart('') Args() {
+    my ( $self, $c ) = @_;
+    $c->response->body( 'Page not found' );
+    $c->response->status(404);
+}
+
+sub end : Action {}
+
+__PACKAGE__->meta->make_immutable;
+
+1;
@@ -0,0 +1,21 @@
+package ChainedActionsApp;
+use Moose;
+use namespace::autoclean;
+
+use Catalyst::Runtime 5.80;
+
+use Catalyst qw//;
+
+extends 'Catalyst';
+
+our $VERSION = "0.01";
+$VERSION = eval $VERSION;
+
+__PACKAGE__->config(
+  name => 'ChainedActionsApp',
+  disable_component_regex_fallback => 1,
+);
+
+__PACKAGE__->setup;
+
+1;
@@ -0,0 +1,30 @@
+package DeprecatedActionsInAppClassTestApp;
+
+use strict;
+use warnings;
+use Catalyst;
+
+our $VERSION = '0.01';
+
+__PACKAGE__->config( name => 'DeprecatedActionsInAppClassTestApp', root => '/some/dir' );
+__PACKAGE__->log(DeprecatedActionsInAppClassTestApp::Log->new);
+__PACKAGE__->setup;
+
+sub foo : Local {
+    my ($self, $c) = @_;
+    $c->res->body('OK');
+}
+
+package DeprecatedActionsInAppClassTestApp::Log;
+use strict;
+use warnings;
+use base qw/Catalyst::Log/;
+
+our $warnings;
+
+sub warn {
+    my ($self, $warning) = @_;
+    $warnings++ if $warning =~ /action methods .+ found defined/i;
+}
+
+1;
@@ -0,0 +1,18 @@
+package DeprecatedTestApp::C::Root;
+use strict;
+use warnings;
+use base qw/Catalyst::Controller/;
+
+__PACKAGE__->config->{namespace} = '';
+
+sub index : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body('root index');
+}
+
+sub req_user : Local {
+    my ( $self, $c ) = @_;
+    $c->res->body('REMOTE_USER = ' . $c->req->user);
+}
+
+1;
@@ -0,0 +1,14 @@
+package DeprecatedTestApp;
+
+use strict;
+use Catalyst qw/
+    Test::Deprecated
+/;
+
+our $VERSION = '0.01';
+
+__PACKAGE__->config( name => 'DeprecatedTestApp', root => '/some/dir' );
+
+__PACKAGE__->setup;
+
+1;
@@ -0,0 +1,7 @@
+package NullPackage;
+# Do nothing class, there should be no code or symbols defined here..
+# Loading this works fine in 5.70, but a die was introduced in 5.80 which caused
+# it to fail. This has been changed to a warning to maintain back-compat.
+# See Catalyst::Utils::ensure_class_loaded() for more info.
+1;
+
@@ -0,0 +1,62 @@
+package PluginTestApp::Controller::Root;
+use Test::More;
+
+use base 'Catalyst::Controller';
+
+#use Catalyst qw(
+#        Test::Plugin
+#        +TestApp::Plugin::FullyQualified
+#        );
+
+__PACKAGE__->config->{namespace} = '';
+
+sub compile_time_plugins : Local {
+    my ( $self, $c ) = @_;
+
+    isa_ok $c, 'Catalyst::Plugin::Test::Plugin';
+    isa_ok $c, 'TestApp::Plugin::FullyQualified';
+
+    can_ok $c, 'registered_plugins';
+    $c->_test_plugins;
+
+    $c->res->body("ok");
+}
+
+sub run_time_plugins : Local {
+    my ( $self, $c ) = @_;
+
+    $c->_test_plugins;
+    my $faux_plugin = 'Faux::Plugin';
+
+# Trick perl into thinking the plugin is already loaded
+    $INC{'Faux/Plugin.pm'} = 1;
+
+    ref($c)->plugin( faux => $faux_plugin );
+
+    isa_ok $c, 'Catalyst::Plugin::Test::Plugin';
+
+    # applied parameterized role
+    if (eval { require MooseX::Role::Parameterized; 1 }) {
+        can_ok $c, 'affe';
+        is $c->affe, 'birne', 'right method created by parameterized role';
+    }
+
+    isa_ok $c, 'TestApp::Plugin::FullyQualified';
+    ok !$c->isa($faux_plugin),
+    '... and it should not inherit from the instant plugin';
+    can_ok $c, 'faux';
+    is $c->faux->count, 1, '... and it should behave correctly';
+    is_deeply [ $c->registered_plugins ],
+    [
+        qw/Catalyst::Plugin::Test::Plugin
+        Faux::Plugin
+        TestApp::Plugin::FullyQualified/
+        ],
+    'registered_plugins() should report all plugins';
+    ok $c->registered_plugins('Faux::Plugin'),
+    '... and even the specific instant plugin';
+
+    $c->res->body("ok");
+}
+
+1;
@@ -1,52 +1,13 @@
 package PluginTestApp;
 use Test::More;
 
-use Catalyst qw(
-        Test::Plugin
-        +TestApp::Plugin::FullyQualified
-        );
-
-sub compile_time_plugins : Local {
-    my ( $self, $c ) = @_;
-
-    isa_ok $c, 'Catalyst::Plugin::Test::Plugin';
-    isa_ok $c, 'TestApp::Plugin::FullyQualified';
-
-    can_ok $c, 'registered_plugins';
-    $c->_test_plugins;
-
-    $c->res->body("ok");
-}
-
-sub run_time_plugins : Local {
-    my ( $self, $c ) = @_;
-
-    $c->_test_plugins;
-    my $faux_plugin = 'Faux::Plugin';
-
-# Trick perl into thinking the plugin is already loaded
-    $INC{'Faux/Plugin.pm'} = 1;
-
-    __PACKAGE__->plugin( faux => $faux_plugin );
-
-    isa_ok $c, 'Catalyst::Plugin::Test::Plugin';
-    isa_ok $c, 'TestApp::Plugin::FullyQualified';
-    ok !$c->isa($faux_plugin),
-    '... and it should not inherit from the instant plugin';
-    can_ok $c, 'faux';
-    is $c->faux->count, 1, '... and it should behave correctly';
-    is_deeply [ $c->registered_plugins ],
-    [
-        qw/Catalyst::Plugin::Test::Plugin
-        Faux::Plugin
-        TestApp::Plugin::FullyQualified/
-        ],
-    'registered_plugins() should report all plugins';
-    ok $c->registered_plugins('Faux::Plugin'),
-    '... and even the specific instant plugin';
-
-    $c->res->body("ok");
-}
+use Catalyst (
+    'Test::Plugin',
+    '+TestApp::Plugin::FullyQualified',
+    (eval { require MooseX::Role::Parameterized; 1 }
+        ? ('+TestApp::Plugin::ParameterizedRole' => { method_name => 'affe' })
+        : ()),
+);
 
 sub _test_plugins {
     my $c = shift;
@@ -0,0 +1,9 @@
+package ScriptTestApp::Script::Bar;
+use Moose;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+1;
@@ -0,0 +1,7 @@
+package ScriptTestApp::Script::CompileTest;
+use Moose;
+use namespace::autoclean;
+
+die("Does not compile");
+
+1;
@@ -0,0 +1,9 @@
+package ScriptTestApp::Script::Foo;
+use Moose;
+use namespace::autoclean;
+
+with 'Catalyst::ScriptRole';
+
+sub run { __PACKAGE__ }
+
+1;
@@ -9,7 +9,7 @@ sub execute {
     my $self = shift;
     my ( $controller, $c, $test ) = @_;
     $c->res->header( 'X-TestAppActionTestBefore', $test );
-    $self->NEXT::execute( @_ );
+    $self->next::method( @_ );
 }
 
 1;
@@ -0,0 +1,17 @@
+package TestApp::Action::TestExtraArgsAction;
+
+use Moose;
+use namespace::autoclean;
+
+extends 'Catalyst::Action';
+
+has [qw/extra_arg another_extra_arg/] => (is => 'ro');
+
+after execute => sub {
+    my ($self, $controller, $ctx) = @_;
+    $ctx->response->header('X-TestExtraArgsAction' => join q{,} => $self->extra_arg, $self->another_extra_arg);
+};
+
+__PACKAGE__->meta->make_immutable;
+
+1;
@@ -9,7 +9,10 @@ sub execute {
     my $self = shift;
     my ( $controller, $c, $test ) = @_;
     $c->res->header( 'X-TestAppActionTestMyAction', 'MyAction works' );
-    $self->NEXT::execute(@_);
+    $c->res->header( 'X-Component-Name-Action', $controller->catalyst_component_name);
+    $c->res->header( 'X-Component-Instance-Name-Action', ref($controller));
+    $c->res->header( 'X-Class-In-Action', $self->class);
+    $self->next::method(@_);
 }
 
 1;
@@ -3,6 +3,16 @@ package TestApp::Controller::Action::Action;
 use strict;
 use base 'TestApp::Controller::Action';
 
+__PACKAGE__->config(
+    actions => {
+        action_action_five => { ActionClass => '+Catalyst::Action::TestBefore' },
+    },
+    action_args => {
+        '*'                 => { extra_arg         => 42 },
+        action_action_seven => { another_extra_arg => 23 },
+    },
+);
+
 sub action_action_one : Global : ActionClass('TestBefore') {
     my ( $self, $c ) = @_;
     $c->res->header( 'X-Action', $c->stash->{test} );
@@ -25,4 +35,20 @@ sub action_action_four : Global : MyAction('TestMyAction') {
     $c->forward('TestApp::View::Dump::Request');
 }
 
+sub action_action_five : Global {
+    my ( $self, $c ) = @_;
+    $c->res->header( 'X-Action', $c->stash->{test} );
+    $c->forward('TestApp::View::Dump::Request');
+}
+
+sub action_action_six : Global : ActionClass('~TestMyAction') {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
+sub action_action_seven : Global : ActionClass('~TestExtraArgsAction') {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
 1;
@@ -0,0 +1,35 @@
+package TestApp::Controller::Action::Chained::ArgsOrder;
+use warnings;
+use strict;
+
+use base qw( Catalyst::Controller );
+
+#
+#   This controller builds a simple chain of three actions that
+#   will output the arguments they got passed to @_ after the
+#   context object. We do this to test if that passing works
+#   as it should.
+#
+
+sub base  :Chained('/') PathPart('argsorder') CaptureArgs(0) {
+    my ( $self, $c, $arg ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'base', $arg;
+}
+
+sub index :Chained('base') PathPart('') Args(0) {
+    my ( $self, $c, $arg ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'index', $arg;
+}
+
+sub all  :Chained('base') PathPart('') Args() {
+    my ( $self, $c, $arg ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'all', $arg;
+}
+
+sub end : Private {
+    my ( $self, $c ) = @_;
+    no warnings 'uninitialized';
+    $c->response->body( join '; ', @{ $c->stash->{ passed_args } } );
+}
+
+1;
@@ -0,0 +1,66 @@
+package TestApp::Controller::Action::Chained::CaptureArgs;
+use warnings;
+use strict;
+
+use base qw( Catalyst::Controller );
+
+#
+#   This controller build the following patterns of URI:
+#      /captureargs/*/*
+#      /captureargs/*/*/edit
+#      /captureargs/*
+#      /captureargs/*/edit
+#      /captureargs/test/*
+#   It will output the arguments they got passed to @_ after the
+#   context object. 
+#   /captureargs/one/edit should not dispatch to /captureargs/*/*
+#   /captureargs/test/one should not dispatch to /captureargs/*/*
+
+sub base  :Chained('/') PathPart('captureargs') CaptureArgs(0) {
+    my ( $self, $c, $arg ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'base';
+}
+
+sub two_args :Chained('base') PathPart('') CaptureArgs(2) {
+    my ( $self, $c, $arg1, $arg2 ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'two_args', $arg1, $arg2;
+}
+
+sub one_arg :Chained('base') ParthPart('') CaptureArgs(1) {
+    my ( $self, $c, $arg ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'one_arg', $arg;
+}
+
+sub edit_two_args  :Chained('two_args') PathPart('edit') Args(0) {
+    my ( $self, $c ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'edit_two_args';
+}
+
+sub edit_one_arg :Chained('one_arg') PathPart('edit') Args(0) {
+    my ( $self, $c ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'edit_one_arg';
+}
+
+sub view_two_args :Chained('two_args') PathPart('') Args(0) {
+    my ( $self, $c ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'view_two_args';
+}
+
+sub view_one_arg :Chained('one_arg') PathPart('') Args(0) {
+    my ( $self, $c ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'view_one_arg';
+}
+
+sub test_plus_arg :Chained('base') PathPart('test') Args(1) {
+    my ( $self, $c, $arg ) = @_;
+    push @{ $c->stash->{ passed_args } }, 'test_plus_arg', $arg;
+}
+
+
+sub end : Private {
+    my ( $self, $c ) = @_;
+    no warnings 'uninitialized';
+    $c->response->body( join '; ', @{ $c->stash->{ passed_args } } );
+}
+
+1;
@@ -30,8 +30,7 @@ sub cross2 :PathPart('end') :Chained('/action/chained/bar/cross1') :Args(1) { }
 #
 sub to_root : Chained('/') PathPart('action/chained/to_root') {
     my ( $self, $c ) = @_;
-    my $uri = $c->uri_for(
-        $c->controller('Root')->action_for('chain_root_index') );
+    my $uri = $c->uri_for_action('/chain_root_index');
     $c->res->body( "URI:$uri" );
     $c->stash->{no_end}++;
 }
@@ -0,0 +1,10 @@
+package TestApp::Controller::Action::Chained::ParentChain::Relative;
+use warnings;
+use strict;
+
+use base qw/ Catalyst::Controller /;
+
+# using ../ to go up more than one level
+sub chained_rel_two : Chained('../../one') Args(2) { }
+
+1;
@@ -10,4 +10,16 @@ use base qw/ Catalyst::Controller /;
 #
 sub child :Chained('.') :Args(1) { }
 
+# Should be at /chained/rootdef/*/chained_rel/*/*
+sub chained_rel :Chained('../one') Args(2) {
+}
+
+# Should chain to loose in parent namespace - i.e. at /chained/loose/*/loose/*/*
+sub loose : ChainedParent Args(2) {
+}
+
+# Should be at /chained/cross/*/up_down/*
+sub up_down : Chained('../bar/cross1') Args(1) {
+}
+
 1;
@@ -0,0 +1,12 @@
+package TestApp::Controller::Action::Chained::PathPrefix;
+
+use strict;
+use warnings;
+
+use base qw/Catalyst::Controller/;
+
+# this is kinda the same thing as: sub instance : Path {}
+# it should respond to: /action/chained/pathprefix/*
+sub instance : Chained('/') PathPrefix Args(1) { }
+
+1;
@@ -3,6 +3,8 @@ package TestApp::Controller::Action::Chained;
 use strict;
 use warnings;
 
+use HTML::Entities;
+
 use base qw/Catalyst::Controller/;
 
 sub begin :Private { }
@@ -15,7 +17,11 @@ sub begin :Private { }
 #
 #   Simple parent/child action test
 #
-sub foo  :PathPart('chained/foo')  :CaptureArgs(1) :Chained('/') { }
+sub foo  :PathPart('chained/foo')  :CaptureArgs(1) :Chained('/') {
+    my ( $self, $c, @args ) = @_;
+    die "missing argument" unless @args;
+    die "more than 1 argument" if @args > 1;
+}
 sub endpoint  :PathPart('end')  :Chained('/action/chained/foo')  :Args(1) { }
 
 #
@@ -175,6 +181,37 @@ sub cc_b		: Chained('cc_base') 	PathPart('b') 				CaptureArgs(0) { }
 sub cc_b_link	: Chained('cc_b') 	 	PathPart('') 				CaptureArgs(1) { }
 sub cc_b_anchor	: Chained('cc_b_link')  PathPart('anchor.html') 	Args() 		   { }
 
+#
+#   Test static paths vs. captures
+#
+
+sub apan        : Chained('/')     CaptureArgs(0) PathPrefix   { }
+sub korv        : Chained('apan')  CaptureArgs(0) PathPart('') { }
+sub wurst       : Chained('apan')  CaptureArgs(1) PathPart('') { }
+sub static_end  : Chained('korv')  Args(0)                     { }
+sub capture_end : Chained('wurst') Args(0)        PathPart('') { }
+
+
+# */search vs doc/*
+sub view : Chained('/') PathPart('chained') CaptureArgs(1) {}
+sub star_search : Chained('view') PathPart('search') Args(0) { }
+sub doc_star : Chained('/') PathPart('chained/doc') Args(1) {}
+
+sub return_arg : Chained('view') PathPart('return_arg') Args(1) {}
+
+sub return_arg_decoded : Chained('/') PathPart('chained/return_arg_decoded') Args(1) {
+    my ($self, $c) = @_;
+    $c->req->args([ map { decode_entities($_) } @{ $c->req->args }]);
+}
+
+sub roundtrip_urifor : Chained('/') PathPart('chained/roundtrip_urifor') CaptureArgs(1) {}
+sub roundtrip_urifor_end : Chained('roundtrip_urifor') PathPart('') Args(1) {
+    my ($self, $c) = @_;
+    # This should round-trip, always - i.e. the uri you put in should come back out.
+    $c->res->body($c->uri_for($c->action, $c->req->captures, @{$c->req->args}, $c->req->parameters));
+    $c->stash->{no_end} = 1;
+}
+
 sub end :Private {
   my ($self, $c) = @_;
   return if $c->stash->{no_end};
@@ -57,6 +57,11 @@ sub with_method_and_args : Local {
     $c->res->body( $c->req->args->[0] );
 }
 
+sub to_action_object : Local {
+    my ( $self, $c ) = @_;
+    $c->forward($self->action_for('embed'), [qw/mtfnpy/]);
+}
+
 sub args : Local {
     my ( $self, $c, $val ) = @_;
     die "Expected argument 'new', got '$val'" unless $val eq 'new';
@@ -85,4 +90,9 @@ sub class_forward_test_action : Local {
     $c->forward(qw/TestApp class_forward_test_method/);
 }
 
+sub forward_to_uri_check : Local {
+    my ( $self, $c ) = @_;
+    $c->forward( 'Action::ForwardTo', 'uri_check' );
+}
+
 1;
@@ -0,0 +1,11 @@
+package TestApp::Controller::Action::ForwardTo;
+
+use strict;
+use base 'TestApp::Controller::Action';
+
+sub uri_check : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body( $c->uri_for('foo/bar')->path );
+}
+
+1;
@@ -0,0 +1,102 @@
+package TestApp::Controller::Action::Go;
+
+use strict;
+use base 'TestApp::Controller::Action';
+
+sub one : Local {
+    my ( $self, $c ) = @_;
+    $c->go('two');
+}
+
+sub two : Private {
+    my ( $self, $c ) = @_;
+    $c->go('three');
+}
+
+sub three : Local {
+    my ( $self, $c ) = @_;
+    $c->go( $self, 'four' );
+}
+
+sub four : Private {
+    my ( $self, $c ) = @_;
+    $c->go('/action/go/five');
+}
+
+sub five : Local {
+    my ( $self, $c ) = @_;
+    $c->forward('View::Dump::Request');
+}
+
+sub inheritance : Local {
+    my ( $self, $c ) = @_;
+    $c->go('/action/inheritance/a/b/default');
+}
+
+sub global : Local {
+    my ( $self, $c ) = @_;
+    $c->go('/global_action');
+}
+
+sub with_args : Local {
+    my ( $self, $c, $arg ) = @_;
+    $c->go( 'args', [$arg] );
+}
+
+sub with_method_and_args : Local {
+    my ( $self, $c, $arg ) = @_;
+    $c->go( qw/TestApp::Controller::Action::Go args/, [$arg] );
+}
+
+sub args : Local {
+    my ( $self, $c, $val ) = @_;
+    die "passed argument does not match args" unless $val eq $c->req->args->[0];
+    $c->res->body($val);
+}
+
+sub go_die : Local {
+    my ( $self, $c, $val ) = @_;
+    eval { $c->go( 'args', [qq/new/] ) };
+    $c->res->body( $@ ? $@ : "go() did not die" );
+    die $Catalyst::GO;
+}
+
+sub go_chained : Local {
+    my ( $self, $c, $val ) = @_;
+    $c->go('/action/chained/foo/spoon', ['captureme'], [qw/arg1 arg2/]);
+}
+
+sub view : Local {
+    my ( $self, $c, $val ) = @_;
+    eval { $c->go('View::Dump') };
+    $c->res->body( $@ ? $@ : "go() did not die" );
+}
+
+sub model : Local {
+    my ( $self, $c, $val ) = @_;
+    eval { $c->go('Model::Foo') };
+    $c->res->body( $@ ? $@ : "go() did not die" );
+}
+
+sub args_embed_relative : Local {
+    my ( $self, $c ) = @_;
+    $c->go('embed/ok');
+}
+
+sub args_embed_absolute : Local {
+    my ( $self, $c ) = @_;
+    $c->go('/action/go/embed/ok');
+}
+
+sub embed : Local {
+    my ( $self, $c, $ok ) = @_;
+    $ok ||= 'not ok';
+    $c->res->body($ok);
+}
+
+sub class_go_test_action : Local {
+    my ( $self, $c ) = @_;
+    $c->go(qw/TestApp/);
+}
+
+1;
@@ -70,5 +70,17 @@ sub end : Private {
     my ( $self, $c ) = @_;
 }
 
+package TestApp::Controller::Action::Inheritance::B;
+
+use strict;
+use base 'TestApp::Controller::Action';
+
+# check configuration for an inherited action
+__PACKAGE__->config(
+    action => {
+        begin => {}
+    }
+);
+
 1;
 
@@ -23,4 +23,9 @@ sub four : Action Path('four/five/six') {
     $c->forward('TestApp::View::Dump::Request');
 }
 
+sub five : Action Local Args(1) {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
 1;
@@ -7,6 +7,7 @@ __PACKAGE__->config(
     actions => {
       'one' => { 'Path' => [ 'a path with spaces' ] },
       'two' => { 'Path' => "åäö" },
+      'six' => { 'Local' => undef },
     },
 );
 
@@ -35,4 +36,9 @@ sub five : Path( "spaces_near_parens_doubleq" ) {
     $c->forward('TestApp::View::Dump::Request');
 }
 
+sub six {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
 1;
@@ -8,27 +8,27 @@ sub default : Private {
     $c->res->output('access denied');
 }
 
-sub one : Private { 
+sub one : Private {
     my ( $self, $c ) = @_;
     $c->res->output('access allowed');
 }
 
-sub two : Private Relative {
+sub two : Private {
     my ( $self, $c ) = @_;
     $c->res->output('access allowed');
 }
 
-sub three : Private Absolute {
+sub three : Private {
     my ( $self, $c ) = @_;
     $c->res->output('access allowed');
 }
 
-sub four : Private Path('/action/private/four') {
+sub four : Private {
     my ( $self, $c ) = @_;
     $c->res->output('access allowed');
 }
 
-sub five : Private Path('five') {
+sub five : Private {
     my ( $self, $c ) = @_;
     $c->res->output('access allowed');
 }
@@ -18,4 +18,18 @@ sub three : Action LocalRegex('^(mandatory)(/optional)?$'){
     $c->forward('TestApp::View::Dump::Request');
 }
 
+sub four : Action Regex('^action/regexp/redirect/(\w+)/universe/(\d+)/everything$') {
+    my ( $self, $c ) = @_;
+    $c->res->redirect(
+        $c->uri_for($c->action, $c->req->captures,
+            @{$c->req->arguments}, $c->req->params
+        )
+    );
+}
+
+sub one_backslashes : Action Regex('^action/regexp/(\w+)/(\d+)\.html$') {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
 1;
@@ -16,8 +16,8 @@ EOF
 
 sub body : Local {
     my ( $self, $c ) = @_;
-    
-    my $file = "$FindBin::Bin/01use.t";
+
+    my $file = "$FindBin::Bin/../lib/TestApp/Controller/Action/Streaming.pm";
     my $fh = IO::File->new( $file, 'r' );
     if ( defined $fh ) {
         $c->res->body( $fh );
@@ -27,4 +27,16 @@ sub body : Local {
     }
 }
 
+sub body_large : Local {
+    my ($self, $c) = @_;
+
+    # more than one write with the default chunksize
+    my $size = 128 * 1024;
+
+    my $data = "\0" x $size;
+    open my $fh, '<', \$data;
+    $c->res->content_length($size);
+    $c->res->body($fh);
+}
+
 1;
@@ -0,0 +1,17 @@
+***************
+*** 17,23 ****
+  sub body : Local {
+      my ( $self, $c ) = @_;
+      
+-     my $file = "$FindBin::Bin/01use.t";
+      my $fh = IO::File->new( $file, 'r' );
+      if ( defined $fh ) {
+          $c->res->body( $fh );
+--- 17,23 ----
+  sub body : Local {
+      my ( $self, $c ) = @_;
+      
++     my $file = "$FindBin::Bin/02pod.t";
+      my $fh = IO::File->new( $file, 'r' );
+      if ( defined $fh ) {
+          $c->res->body( $fh );
@@ -17,4 +17,24 @@ sub relative_two : Local {
     $c->forward( 'TestApp::Controller::Action::Forward', 'one' );
 }
 
+sub relative_go : Local {
+    my ( $self, $c ) = @_;
+    $c->go('/action/go/one');
+}
+
+sub relative_go_two : Local {
+    my ( $self, $c ) = @_;
+    $c->go( 'TestApp::Controller::Action::Go', 'one' );
+}
+
+sub relative_visit : Local {
+    my ( $self, $c ) = @_;
+    $c->visit('/action/visit/one');
+}
+
+sub relative_visit_two : Local {
+    my ( $self, $c ) = @_;
+    $c->visit( 'TestApp::Controller::Action::Visit', 'one' );
+}
+
 1;
@@ -0,0 +1,104 @@
+package TestApp::Controller::Action::Visit;
+
+use strict;
+use base 'TestApp::Controller::Action';
+
+sub one : Local {
+    my ( $self, $c ) = @_;
+    $c->visit('two');
+}
+
+sub two : Private {
+    my ( $self, $c ) = @_;
+    $c->visit('three');
+}
+
+sub three : Local {
+    my ( $self, $c ) = @_;
+    $c->visit( $self, 'four' );
+}
+
+sub four : Private {
+    my ( $self, $c ) = @_;
+    $c->visit('/action/visit/five');
+}
+
+sub five : Local {
+    my ( $self, $c ) = @_;
+    $c->forward('View::Dump::Request');
+}
+
+sub inheritance : Local {
+    my ( $self, $c ) = @_;
+    $c->visit('/action/inheritance/a/b/default');
+}
+
+sub global : Local {
+    my ( $self, $c ) = @_;
+    $c->visit('/global_action');
+}
+
+sub with_args : Local {
+    my ( $self, $c, $arg ) = @_;
+    $c->visit( 'args', [$arg] );
+}
+
+sub with_method_and_args : Local {
+    my ( $self, $c, $arg ) = @_;
+    $c->visit( qw/TestApp::Controller::Action::Visit args/, [$arg] );
+}
+
+sub args : Local {
+    my ( $self, $c, $val ) = @_;
+    die "passed argument does not match args" unless $val eq $c->req->args->[0];
+    $c->res->body($val);
+}
+
+sub visit_die : Local {
+    my ( $self, $c, $val ) = @_;
+    eval { $c->visit( 'args', [qq/new/] ) };
+    $c->res->body( $@ ? $@ : "visit() doesn't die" );
+}
+
+sub visit_chained : Local {
+    my ( $self, $c, $val, $capture, @args ) = @_;
+    my @cap_and_args = ([$capture], [@args]);
+      $val eq 1 ? $c->visit( '/action/chained/foo/spoon',                                 @cap_and_args)
+    : $val eq 2 ? $c->visit( qw/ Action::Chained::Foo spoon /,                            @cap_and_args)
+    :             $c->visit( $c->controller('Action::Chained::Foo')->action_for('spoon'), @cap_and_args)
+}
+
+sub view : Local {
+    my ( $self, $c, $val ) = @_;
+    eval { $c->visit('View::Dump') };
+    $c->res->body( $@ ? $@ : "visit() did not die" );
+}
+
+sub model : Local {
+    my ( $self, $c, $val ) = @_;
+    eval { $c->visit('Model::Foo') };
+    $c->res->body( $@ ? $@ : "visit() did not die" );
+}
+
+sub args_embed_relative : Local {
+    my ( $self, $c ) = @_;
+    $c->visit('embed/ok');
+}
+
+sub args_embed_absolute : Local {
+    my ( $self, $c ) = @_;
+    $c->visit('/action/visit/embed/ok');
+}
+
+sub embed : Local {
+    my ( $self, $c, $ok ) = @_;
+    $ok ||= 'not ok';
+    $c->res->body($ok);
+}
+
+sub class_visit_test_action : Local {
+    my ( $self, $c ) = @_;
+    $c->visit(qw/TestApp/);
+}
+
+1;
@@ -0,0 +1,39 @@
+package Anon::Trait;
+use Moose::Role -traits => 'MethodAttributes'; # Needed for role composition to work correctly with anon classes.
+
+after test => sub {
+    my ($self, $c) = @_;
+    $c->res->header('X-Anon-Trait-Applied', 1);
+};
+
+no Moose::Role;
+
+package TestApp::Controller::Anon;
+use Moose;
+use Moose::Util qw/find_meta/;
+use namespace::clean -except => 'meta';
+BEGIN { extends 'Catalyst::Controller' };
+
+sub COMPONENT { # Don't do this yourself, use CatalystX::Component::Traits!
+    my ($class, $app, $args) = @_;
+
+    my $meta = $class->meta->create_anon_class(
+            superclasses => [ $class->meta->name ],
+            roles        => ['Anon::Trait'],
+            cache        => 1,
+    );
+    # Special move as the methodattributes trait has changed our metaclass..
+    $meta = find_meta($meta->name);
+
+    $class = $meta->name;
+    $class->new($app, $args);
+}
+
+sub test : Local ActionClass('+TestApp::Action::TestMyAction') {
+    my ($self, $c) = @_;
+    $c->res->header('X-Component-Name-Controller', $self->catalyst_component_name);
+    $c->res->body('It works');
+}
+
+__PACKAGE__->meta->make_immutable;
+
@@ -1,8 +1,7 @@
 package TestApp::Controller::Args;
 
 use strict;
-use base 'Catalyst::Base';
-use Data::Dumper;
+use base 'Catalyst::Controller';
 
 sub args :Local  {
     my ( $self, $c ) = @_;
@@ -14,4 +13,4 @@ sub params :Local {
     $c->res->body( join('',@_) );
 }
 
-1;
\ No newline at end of file
+1;
@@ -0,0 +1,30 @@
+use strict;
+use warnings;
+
+package My::AttributesBaseClass;
+use base qw( Catalyst::Controller );
+
+sub fetch : Chained('/') PathPrefix CaptureArgs(1) {
+
+}
+
+sub view : PathPart Chained('fetch') Args(0) {
+
+}
+
+sub foo {    # no attributes
+
+}
+
+package TestApp::Controller::Attributes;
+use base qw(My::AttributesBaseClass);
+
+sub view {    # override attributes to "hide" url
+
+}
+
+sub foo : Local {
+
+}
+
+1;
@@ -0,0 +1,29 @@
+package TestApp::Controller::ContextClosure;
+
+use Moose;
+
+BEGIN {
+    extends 'Catalyst::Controller';
+    with 'Catalyst::Component::ContextClosure';
+}
+
+sub normal_closure : Local {
+    my ($self, $ctx) = @_;
+    $ctx->stash(closure => sub {
+        $ctx->response->body('from normal closure');
+    });
+    $ctx->response->body('stashed normal closure');
+}
+
+sub context_closure : Local {
+    my ($self, $ctx) = @_;
+    $ctx->stash(closure => $self->make_context_closure(sub {
+        my ($ctx) = @_;
+        $ctx->response->body('from context closure');
+    }, $ctx));
+    $ctx->response->body('stashed context closure');
+}
+
+__PACKAGE__->meta->make_immutable;
+
+1;
@@ -1,26 +1,22 @@
 package TestApp::Controller::Dump;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
-sub default : Action Private {
+sub default : Action {
     my ( $self, $c ) = @_;
     $c->forward('TestApp::View::Dump');
 }
 
 sub env : Action Relative {
     my ( $self, $c ) = @_;
-    $c->stash( env => \%ENV );
-    $c->forward('TestApp::View::Dump');
-}
-
-sub parameters : Action Relative {
-    my ( $self, $c ) = @_;
-    $c->forward('TestApp::View::Dump::Parameters');
+    $c->forward('TestApp::View::Dump::Env');
 }
 
 sub request : Action Relative {
     my ( $self, $c ) = @_;
+    $c->req->params(undef); # Should be a no-op, and be ignored.
+                            # Back compat test for 5.7
     $c->forward('TestApp::View::Dump::Request');
 }
 
@@ -29,4 +25,9 @@ sub response : Action Relative {
     $c->forward('TestApp::View::Dump::Response');
 }
 
+sub body : Action Relative {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Body');
+}
+
 1;
@@ -1,7 +1,7 @@
 package TestApp::Controller::Engine::Request::URI;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub default : Private {
     my ( $self, $c ) = @_;
@@ -32,11 +32,13 @@ sub uri_with : Local {
     my ( $self, $c ) = @_;
 
     # change the current uri
-    my $uri   = $c->req->uri_with( { b => 1 } );
+    my $uri   = $c->req->uri_with( { b => 1, c => undef } );
     my %query = $uri->query_form;
     
     $c->res->header( 'X-Catalyst-Param-a' => $query{ a } );
     $c->res->header( 'X-Catalyst-Param-b' => $query{ b } );
+    $c->res->header( 'X-Catalyst-Param-c' => exists($query{ c }) ? $query{ c } : '--notexists--' );
+    $c->res->header( 'X-Catalyst-query' => $uri->query);
     
     $c->forward('TestApp::View::Dump::Request');
 }
@@ -77,4 +79,26 @@ sub uri_with_undef : Local {
     $c->forward('TestApp::View::Dump::Request');
 }
 
+sub uri_with_undef_only : Local {
+    my ( $self, $c ) = @_;
+
+    my $uri = $c->req->uri_with( { a => undef } );
+    
+    $c->res->header( 'X-Catalyst-uri-with' => "$uri" );
+    $c->forward('TestApp::View::Dump::Request');
+}
+
+sub uri_with_undef_ignore : Local {
+    my ( $self, $c ) = @_;
+
+    my $uri = $c->req->uri_with( { a => 1, b => undef } );
+    
+    my %query = $uri->query_form;
+    $c->res->header( 'X-Catalyst-uri-with' => "$uri" );
+    $c->res->header( 'X-Catalyst-Param-a' => $query{ a } );
+    $c->res->header( 'X-Catalyst-Param-b' => $query{ b } );
+    $c->res->header( 'X-Catalyst-Param-c' => $query{ c } );
+    $c->forward('TestApp::View::Dump::Request');
+}
+
 1;
@@ -1,7 +1,7 @@
 package TestApp::Controller::Engine::Request::Uploads;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub slurp : Relative {
     my ( $self, $c ) = @_;
@@ -1,19 +1,19 @@
 package TestApp::Controller::Engine::Response::Cookies;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub one : Local {
     my ( $self, $c ) = @_;
-    $c->res->cookies->{Catalyst} = { value => 'Cool',     path => '/bah' };
-    $c->res->cookies->{Cool}     = { value => 'Catalyst', path => '/' };
+    $c->res->cookies->{catalyst} = { value => 'cool',     path => '/bah' };
+    $c->res->cookies->{cool}     = { value => 'catalyst', path => '/' };
     $c->forward('TestApp::View::Dump::Request');
 }
 
 sub two : Local {
     my ( $self, $c ) = @_;
-    $c->res->cookies->{Catalyst} = { value => 'Cool',     path => '/bah' };
-    $c->res->cookies->{Cool}     = { value => 'Catalyst', path => '/' };
+    $c->res->cookies->{catalyst} = { value => 'cool',     path => '/bah' };
+    $c->res->cookies->{cool}     = { value => 'catalyst', path => '/' };
     $c->res->redirect('http://www.google.com/');
 }
 
@@ -1,7 +1,7 @@
 package TestApp::Controller::Engine::Response::Errors;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub one : Relative {
     my ( $self, $c ) = @_;
@@ -1,7 +1,7 @@
 package TestApp::Controller::Engine::Response::Headers;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub one : Relative {
     my ( $self, $c ) = @_;
@@ -1,7 +1,7 @@
 package TestApp::Controller::Engine::Response::Large;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub one : Relative {
     my ( $self, $c ) = @_;
@@ -0,0 +1,25 @@
+package TestApp::Controller::Engine::Response::Print;
+
+use strict;
+use base 'Catalyst::Controller';
+
+sub one :Relative {
+    my ( $self, $c ) = @_;
+    
+    $c->res->print("foo");
+}
+
+sub two :Relative {
+    my ( $self, $c ) = @_;
+
+    $c->res->print(qw/foo bar/);
+}
+
+sub three :Relative {
+    my ( $self, $c ) = @_;
+
+    local $, = ',';
+    $c->res->print(qw/foo bar baz/);
+}
+
+1;
@@ -1,7 +1,7 @@
 package TestApp::Controller::Engine::Response::Redirect;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub one : Relative {
     my ( $self, $c ) = @_;
@@ -1,7 +1,7 @@
 package TestApp::Controller::Engine::Response::Status;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub begin : Private {
     my ( $self, $c ) = @_;
@@ -7,7 +7,8 @@ package TestApp::Controller::Fork;
 use strict;
 use warnings;
 use base 'Catalyst::Controller';
-use YAML;
+
+eval 'use YAML';
 
 sub system : Local {
     my ($self, $c, $ls) = @_;
@@ -0,0 +1,30 @@
+package TestApp::Controller::Immutable::HardToReload::Role;
+use Moose::Role; # Role metaclass does not have make_immutable..
+no Moose::Role;
+
+package TestApp::Controller::Immutable::HardToReload;
+use Moose;
+BEGIN { extends 'Catalyst::Controller' }
+no Moose;
+__PACKAGE__->meta->make_immutable;
+
+package # Standard PAUSE hiding technique
+    TestApp::Controller::Immutable::HardToReload::PAUSEHide;
+use Moose;
+BEGIN { extends 'Catalyst::Controller' }
+no Moose;
+__PACKAGE__->meta->make_immutable;
+
+# Not an inner package
+package TestApp::Controller::Immutable2;
+use Moose;
+BEGIN { extends 'Catalyst::Controller' }
+no Moose;
+__PACKAGE__->meta->make_immutable;
+
+# Not even in the app namespace
+package Frobnitz;
+use Moose;
+BEGIN { extends 'Catalyst::Controller' }
+no Moose;
+__PACKAGE__->meta->make_immutable;
@@ -0,0 +1,5 @@
+package TestApp::Controller::Immutable;
+use Moose;
+BEGIN { extends 'Catalyst::Controller' }
+no Moose;
+__PACKAGE__->meta->make_immutable;
@@ -1,7 +1,7 @@
 package TestApp::Controller::Index;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub index : Private {
     my ( $self, $c ) = @_;
@@ -0,0 +1,18 @@
+package TestApp::Controller::Keyword;
+
+use strict;
+use base 'Catalyst::Controller';
+
+#
+# Due to 'actions' being used as an attribute up to cat 5.80003 using this name
+# for an action causes a weird error, as this would be called during BUILD time
+# of the Catalyst::Controller class
+#
+
+sub actions : Local {
+    my ( $self, $c ) = @_;
+    die("Call to controller action method without context! Probably naming clash") unless $c;
+    $c->res->output("Test case for using 'actions' as a catalyst action name\n");
+}
+
+1;
@@ -0,0 +1,10 @@
+package TestApp::Controller::Moose::MethodModifiers;
+use Moose;
+BEGIN { extends qw/TestApp::Controller::Moose/; }
+
+after get_attribute => sub {
+    my ($self, $c) = @_;
+    $c->response->header( 'X-Catalyst-Test-After' => 'after called' );
+};
+
+1;
@@ -0,0 +1,16 @@
+package TestApp::Controller::Moose::NoAttributes;
+use Moose;
+extends qw/Catalyst::Controller/;
+
+__PACKAGE__->config(
+   actions => {
+       test => { Local => undef }
+   }
+);
+
+sub test {
+}
+
+no Moose;
+1;
+
@@ -0,0 +1,33 @@
+package TestApp::Controller::Moose;
+
+use Moose;
+
+use namespace::clean -except => 'meta';
+
+BEGIN { extends qw/Catalyst::Controller/; }
+use MooseX::MethodAttributes; # FIXME - You need to say this if you have
+                              #         modifiers so that you get the correct
+                              #         method metaclass, why does the modifier
+                              #         on MODIFY_CODE_ATTRIBUTES not work.
+
+has attribute => (
+    is      => 'ro',
+    default => 42,
+);
+
+sub get_attribute : Local {
+    my ($self, $c) = @_;
+    $c->response->body($self->attribute);
+}
+
+sub with_local_modifier : Local {
+    my ($self, $c) = @_;
+    $c->forward('get_attribute');
+}
+
+before with_local_modifier => sub {
+    my ($self, $c) = @_;
+    $c->response->header( 'X-Catalyst-Test-Before' => 'before called' );
+};
+
+1;
@@ -16,4 +16,6 @@ sub one :Path :Args(1) { }
 
 sub two :Path :Args(2) { }
 
+sub not_def : Path { }
+
 1;
@@ -1,7 +1,7 @@
 package TestApp::Controller::Priorities::loc_vs_index;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub index :Private { $_[1]->res->body( 'index' ) }
 
@@ -1,7 +1,7 @@
 package TestApp::Controller::Priorities::locre_vs_index;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub index :Private { $_[1]->res->body( 'index' ) }
 
@@ -1,7 +1,7 @@
 package TestApp::Controller::Priorities::path_vs_index;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub index :Private { $_[1]->res->body( 'index' ) }
 
@@ -1,7 +1,7 @@
 package TestApp::Controller::Priorities::re_vs_index;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 sub index :Private { $_[1]->res->body( 'index' ) }
 
@@ -1,7 +1,7 @@
 package TestApp::Controller::Priorities;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::Controller';
 
 #
 #   Regex vs. Local
@@ -1,9 +1,72 @@
 package TestApp::Controller::Root;
-
+use strict;
+use warnings;
 use base 'Catalyst::Controller';
 
 __PACKAGE__->config->{namespace} = '';
 
 sub chain_root_index : Chained('/') PathPart('') Args(0) { }
 
+sub zero : Path('0') {
+    my ( $self, $c ) = @_;
+    $c->res->header( 'X-Test-Class' => ref($self) );
+    $c->response->content_type('text/plain; charset=utf-8');
+    $c->forward('TestApp::View::Dump::Request');
+}
+
+sub localregex : LocalRegex('^localregex$') {
+    my ( $self, $c ) = @_;
+    $c->res->header( 'X-Test-Class' => ref($self) );
+    $c->response->content_type('text/plain; charset=utf-8');
+    $c->forward('TestApp::View::Dump::Request');
+}
+
+sub index : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body('root index');
+}
+
+sub global_action : Private {
+    my ( $self, $c ) = @_;
+    $c->forward('TestApp::View::Dump::Request');
+}
+
+sub class_forward_test_method :Private {
+    my ( $self, $c ) = @_;
+    $c->response->headers->header( 'X-Class-Forward-Test-Method' => 1 );
+}
+
+sub loop_test : Local {
+    my ( $self, $c ) = @_;
+
+    for( 1..1001 ) {
+        $c->forward( 'class_forward_test_method' );
+    }
+}
+
+sub recursion_test : Local {
+    my ( $self, $c ) = @_;
+    $c->forward( 'recursion_test' );
+}
+
+sub base_href_test : Local {
+    my ( $self, $c ) = @_;
+
+    my $body = <<"EndOfBody";
+<html>
+  <head>
+    <base href="http://www.example.com/">
+  </head>
+  <body>
+  </body>
+</html>
+EndOfBody
+
+    $c->response->body($body);
+}
+
+sub end : Private {
+    my ($self,$c) = @_;
+}
+
 1;
@@ -0,0 +1,10 @@
+package TestApp::DispatchType::CustomPostLoad;
+use strict;
+use warnings;
+use base qw/Catalyst::DispatchType::Path/;
+
+# Never match anything..
+sub match { }
+
+1;
+
@@ -0,0 +1,10 @@
+package TestApp::DispatchType::CustomPreLoad;
+use strict;
+use warnings;
+use base qw/Catalyst::DispatchType::Path/;
+
+# Never match anything..
+sub match { }
+
+1;
+
@@ -0,0 +1,12 @@
+package TestApp::Model::ClosuresInConfig;
+use Moose;
+use namespace::clean -except => 'meta';
+
+extends 'TestApp::Model';
+
+# Note - don't call ->config in here until the constructor calls it to
+#        retrieve config, so that we get the 'copy from parent' path, 
+#        and ergo break due to the closure if dclone is used there..
+
+__PACKAGE__->meta->make_immutable;
+
@@ -5,8 +5,12 @@ use warnings;
 
 use base qw/ Catalyst::Model /;
 
+__PACKAGE__->config( 'quux' => 'chunkybacon' );
+
 sub model_foo_method { 1 }
 
+sub model_quux_method { shift->{quux} }
+
 package TestApp::Model::Foo::Bar;
 sub model_foo_bar_method_from_foo { 1 }
 
@@ -0,0 +1,22 @@
+package TestApp::Model::Generating;
+use Moose;
+extends 'Catalyst::Model';
+
+sub BUILD {
+    Class::MOP::Class->create(
+        'TestApp::Model::Generated' => (
+            methods => {
+                foo => sub { 'foo' }
+            }
+        )
+    );
+}
+
+sub expand_modules {
+    return ('TestApp::Model::Generated');
+}
+
+__PACKAGE__->meta->make_immutable;
+no Moose;
+
+1;
@@ -0,0 +1,16 @@
+package TestApp::Model;
+use Moose;
+use namespace::clean -except => 'meta';
+
+extends 'Catalyst::Model';
+
+# Test a closure here, r10394 made this blow up when we clone the config down
+# onto the subclass..
+__PACKAGE__->config(
+    escape_flags => {
+        'js' => sub { ${ $_[0] } =~ s/\'/\\\'/g; },
+    }
+);
+
+__PACKAGE__->meta->make_immutable;
+
@@ -0,0 +1,26 @@
+package TestApp::Plugin::AddDispatchTypes;
+use strict;
+use warnings;
+use MRO::Compat;
+
+sub setup_dispatcher {
+    my $class = shift;
+
+    ### Load custom DispatchTypes, as done by Catalyst::Plugin::Server
+    # There should be a waaay less ugly method for doing this,
+    # FIXME in 5.9
+    $class->next::method( @_ );
+    $class->dispatcher->preload_dispatch_types(
+        @{$class->dispatcher->preload_dispatch_types},
+        qw/ +TestApp::DispatchType::CustomPreLoad /
+    );
+    $class->dispatcher->postload_dispatch_types(
+        @{$class->dispatcher->postload_dispatch_types},
+        qw/ +TestApp::DispatchType::CustomPostLoad /
+    );
+
+    return $class;
+}
+
+1;
+
@@ -0,0 +1,18 @@
+package TestApp::Plugin::ParameterizedRole;
+
+use MooseX::Role::Parameterized;
+use namespace::autoclean;
+
+parameter method_name => (
+    isa      => 'Str',
+    required => 1,
+);
+
+role {
+    my $p = shift;
+    my $method_name = $p->method_name;
+
+    method $method_name => sub { 'birne' };
+};
+
+1;
@@ -0,0 +1,14 @@
+package TestApp::RequestBaseBug;
+
+use base 'Catalyst::Request';
+
+sub uri {
+    my $self = shift;
+
+# this goes into infinite mutual recursion
+    $self->base;
+
+    $self->SUPER::uri(@_)
+}
+
+1;
@@ -0,0 +1,15 @@
+package TestApp::Role;
+use Moose::Role;
+use namespace::clean -except => 'meta';
+
+requires 'fully_qualified'; # Comes from TestApp::Plugin::FullyQualified
+
+our $SETUP_FINALIZE = 0;
+our $SETUP_DISPATCHER = 0;
+
+before 'setup_finalize' => sub { $SETUP_FINALIZE++ };
+
+before 'setup_dispatcher' => sub { $SETUP_DISPATCHER++ }; 
+
+1;
+
@@ -0,0 +1,11 @@
+package TestApp::View::Dump::Body;
+
+use strict;
+use base qw[TestApp::View::Dump];
+
+sub process {
+    my ( $self, $c ) = @_;
+    return $self->SUPER::process( $c, $c->request->{_body} ); # FIXME, accessor doesn't work?
+}
+
+1;
@@ -0,0 +1,12 @@
+package TestApp::View::Dump::Env;
+
+use strict;
+use base qw[TestApp::View::Dump];
+
+sub process {
+    my ( $self, $c ) = @_;
+    return $self->SUPER::process( $c, $c->engine->env );
+}
+
+1;
+
@@ -1,11 +0,0 @@
-package TestApp::View::Dump::Parameters;
-
-use strict;
-use base 'TestApp::View::Dump';
-
-sub process {
-    my ( $self, $c ) = @_;
-    return $self->SUPER::process( $c, $c->req->parameters );
-}
-
-1;
@@ -1,10 +1,10 @@
 package TestApp::View::Dump;
 
 use strict;
-use base 'Catalyst::Base';
+use base 'Catalyst::View';
 
 use Data::Dumper ();
-use Scalar::Util qw(weaken);
+use Scalar::Util qw(blessed weaken);
 
 sub dump {
     my ( $self, $reference ) = @_;
@@ -28,25 +28,32 @@ sub process {
     # Force processing of on-demand data
     $c->prepare_body;
 
-    # Remove context from reference if needed
-    my $context = delete $reference->{_context};
-
     # Remove body from reference if needed
+    $reference->{__body_type} = blessed $reference->body
+        if (blessed $reference->{_body});
     my $body = delete $reference->{_body};
 
+    # Remove context from reference if needed
+    my $context = delete $reference->{_context};
+
     if ( my $output =
-        $self->dump( $reference || $c->stash->{dump} || $c->stash ) )
+        $self->dump( $reference ) )
     {
 
         $c->res->headers->content_type('text/plain');
         $c->res->output($output);
 
-        # Repair context
-        $reference->{_context} = $context;
-        weaken( $reference->{_context} );
-
-        # Repair body
-        $reference->{_body} = $body;
+        if ($context) {
+            # Repair context
+            $reference->{_context} = $context;
+            weaken( $reference->{_context} );
+        }
+
+        if ($body) {
+            # Repair body
+            delete $reference->{__body_type};
+            $reference->{_body} = $body;
+        }
 
         return 1;
     }
@@ -2,34 +2,78 @@ package TestApp;
 
 use strict;
 use Catalyst qw/
+    Test::MangleDollarUnderScore
     Test::Errors 
     Test::Headers 
     Test::Plugin
     Test::Inline
     +TestApp::Plugin::FullyQualified
+    +TestApp::Plugin::AddDispatchTypes
+    +TestApp::Role
 /;
 use Catalyst::Utils;
 
+use Moose;
+use namespace::autoclean;
+
+# -----------
+# t/aggregate/unit_core_ctx_attr.t pukes until lazy is true
+package Greeting;
+use Moose;
+sub hello_notlazy { 'hello there' }
+sub hello_lazy    { 'hello there' }
+
+package TestApp;
+has 'my_greeting_obj_notlazy' => (
+   is      => 'ro',
+   isa     => 'Greeting',
+   default => sub { Greeting->new() },
+   handles => [ qw( hello_notlazy ) ],
+   lazy    => 0,
+);
+has 'my_greeting_obj_lazy' => (
+   is      => 'ro',
+   isa     => 'Greeting',
+   default => sub { Greeting->new() },
+   handles => [ qw( hello_lazy ) ],
+   lazy    => 1,
+);
+# -----------
+
 our $VERSION = '0.01';
 
-TestApp->config( name => 'TestApp', root => '/some/dir' );
+TestApp->config( name => 'TestApp', root => '/some/dir', use_request_uri_for_path => 1 );
 
-TestApp->setup;
+# Test bug found when re-adjusting the metaclass compat code in Moose
+# in 292360. Test added to Moose in 4b760d6, but leave this attribute
+# above ->setup so we have some generated methods to be double sure.
+has an_attribute_before_we_change_base_classes => ( is => 'ro');
 
-sub index : Private {
-    my ( $self, $c ) = @_;
-    $c->res->body('root index');
+if ($::setup_leakchecker && eval { Class::MOP::load_class('CatalystX::LeakChecker'); 1 }) {
+    with 'CatalystX::LeakChecker';
+
+    has leaks => (
+        is      => 'ro',
+        default => sub { [] },
+    );
+}
+
+sub found_leaks {
+    my ($ctx, @leaks) = @_;
+    push @{ $ctx->leaks }, @leaks;
 }
 
-sub global_action : Private {
-    my ( $self, $c ) = @_;
-    $c->forward('TestApp::View::Dump::Request');
+sub count_leaks {
+    my ($ctx) = @_;
+    return scalar @{ $ctx->leaks };
 }
 
+TestApp->setup;
+
 sub execute {
     my $c      = shift;
     my $class  = ref( $c->component( $_[0] ) ) || $_[0];
-    my $action = "$_[1]";
+    my $action = $_[1]->reverse;
 
     my $method;
 
@@ -52,7 +96,7 @@ sub execute {
             @executed
         );
     }
-
+    no warnings 'recursion';
     return $c->SUPER::execute(@_);
 }
 
@@ -61,30 +105,12 @@ sub execute {
 sub finalize_error {
     my $c = shift;
     
-    $c->NEXT::finalize_error(@_);
+    $c->next::method(@_);
     
     $c->res->status(500);
     $c->res->body( 'FATAL ERROR: ' . join( ', ', @{ $c->error } ) );
 }
 
-sub class_forward_test_method :Private {
-    my ( $self, $c ) = @_;
-    $c->response->headers->header( 'X-Class-Forward-Test-Method' => 1 );
-}
-
-sub loop_test : Local {
-    my ( $self, $c ) = @_;
-
-    for( 1..1001 ) {
-        $c->forward( 'class_forward_test_method' );
-    }
-}
-
-sub recursion_test : Local {
-    my ( $self, $c ) = @_;
-    $c->forward( 'recursion_test' );
-}
-
 {
     no warnings 'redefine';
     sub Catalyst::Log::error { }
@@ -96,6 +122,6 @@ package Catalyst::Plugin::Test::Inline;
 
 use strict;
 
-use base qw/Catalyst::Base Class::Data::Inheritable/;
+use base qw/Class::Data::Inheritable/;
 
-1;
\ No newline at end of file
+1;
@@ -0,0 +1,12 @@
+package TestAppBadlyImmutable;
+use Catalyst qw/+TestPluginWithConstructor/;
+use Test::More;
+
+__PACKAGE__->setup;
+
+ok !__PACKAGE__->meta->is_immutable, 'Am not already immutable';
+__PACKAGE__->meta->make_immutable( inline_constructor => 0 );
+ok __PACKAGE__->meta->is_immutable, 'Am now immutable';
+
+1;
+
@@ -0,0 +1,21 @@
+package TestAppClassExceptionSimpleTest::Exception;
+use strict;
+use warnings;
+
+sub throw {}
+
+#########
+
+package TestAppClassExceptionSimpleTest;
+use strict;
+use warnings;
+
+use Catalyst::Utils; #< some of the scripts use Catalyst::Utils before MyApp.pm
+
+BEGIN { $Catalyst::Exception::CATALYST_EXCEPTION_CLASS = 'TestAppClassExceptionSimpleTest::Exception'; }
+
+use Catalyst;
+
+__PACKAGE__->setup;
+
+1;
@@ -0,0 +1,22 @@
+package TestAppDoubleAutoBug::Controller::Root;
+
+use base 'Catalyst::Controller';
+
+__PACKAGE__->config->{namespace} = '';
+
+sub auto : Private {
+    my ( $self, $c ) = @_;
+    ++$c->stash->{auto_count};
+    return 1;
+}
+
+sub default : Private {
+    my ( $self, $c ) = @_;
+    $c->res->body( sprintf 'default, auto=%d', $c->stash->{auto_count} );
+}
+
+sub end : Private {
+    my ($self,$c) = @_;
+}
+
+1;
@@ -18,7 +18,7 @@ __PACKAGE__->setup;
 sub execute {
     my $c      = shift;
     my $class  = ref( $c->component( $_[0] ) ) || $_[0];
-    my $action = "$_[1]";
+    my $action = $_[1]->reverse();
 
     my $method;
 
@@ -45,15 +45,5 @@ sub execute {
     return $c->SUPER::execute(@_);
 }
 
+1;
 
-
-sub auto : Private {
-    my ( $self, $c ) = @_;
-    ++$c->stash->{auto_count};
-    return 1;
-}
-
-sub default : Private {
-    my ( $self, $c ) = @_;
-    $c->res->body( sprintf 'default, auto=%d', $c->stash->{auto_count} );
-}
@@ -0,0 +1,48 @@
+package TestAppEncoding::Controller::Root;
+use strict;
+use warnings;
+use base 'Catalyst::Controller';
+use Test::More;
+
+__PACKAGE__->config->{namespace} = '';
+
+sub binary : Local {
+    my ($self, $c) = @_;
+    $c->res->body(do { 
+        open(my $fh, '<', $c->path_to('..', '..', 'catalyst_130pix.gif')) or die $!; 
+        binmode($fh); 
+        local $/ = undef; <$fh>;
+    });
+}
+
+sub binary_utf8 : Local {
+    my ($self, $c) = @_;
+    $c->forward('binary');
+    my $str = $c->res->body;
+    utf8::upgrade($str);
+    ok utf8::is_utf8($str), 'Body is variable width encoded string';
+    $c->res->body($str);
+}
+
+# called by t/aggregate/catalyst_test_utf8.t
+sub utf8_non_ascii_content : Local {
+    use utf8;
+    my ($self, $c) = @_;
+    
+    my $str = 'ʇsʎlɐʇɐɔ';  # 'catalyst' flipped at http://www.revfad.com/flip.html
+    ok utf8::is_utf8($str), '$str is in UTF8 internally';
+    
+    # encode $str into a sequence of octets and turn off the UTF-8 flag, so that
+    # we don't get the 'Wide character in syswrite' error in Catalyst::Engine
+    utf8::encode($str);
+    ok !utf8::is_utf8($str), '$str is a sequence of octets (byte string)';
+    
+    $c->res->body($str);
+}
+
+
+sub end : Private {
+    my ($self,$c) = @_;
+}
+
+1;
@@ -0,0 +1,11 @@
+package TestAppEncoding;
+use strict;
+use warnings;
+use base qw/Catalyst/;
+use Catalyst;
+
+__PACKAGE__->config(name => __PACKAGE__);
+__PACKAGE__->setup;
+
+1;
+
@@ -0,0 +1,15 @@
+package TestAppIndexDefault::Controller::Default;
+
+use base 'Catalyst::Controller';
+
+sub default : Private {
+    my ($self, $c) = @_;
+    $c->res->body('default_default');
+}
+
+sub path_one_arg : Path('/default/') Args(1) {
+    my ($self, $c) = @_;
+    $c->res->body('default_path_one_arg');
+}
+
+1;
@@ -0,0 +1,12 @@
+package TestAppIndexDefault::Controller::IndexChained;
+
+use base 'Catalyst::Controller';
+
+sub index : Chained('/') PathPart('indexchained') CaptureArgs(0) {}
+
+sub index_endpoint : Chained('index') PathPart('') Args(0) {
+    my ($self, $c) = @_;
+    $c->res->body('index_chained');
+}
+
+1;
@@ -0,0 +1,10 @@
+package TestAppIndexDefault::Controller::IndexPrivate;
+
+use base 'Catalyst::Controller';
+
+sub index : Private {
+    my ($self, $c) = @_;
+    $c->res->body('index_private');
+}
+
+1;
@@ -0,0 +1,17 @@
+package TestAppIndexDefault::Controller::Root;
+
+use base 'Catalyst::Controller';
+
+__PACKAGE__->config->{namespace} = '';
+
+sub default : Private {
+    my ($self, $c) = @_;
+    $c->res->body('default');
+}
+
+sub path_one_arg : Path('/') Args(1) {
+    my ($self, $c) = @_;
+    $c->res->body('path_one_arg');
+}
+
+1;
@@ -0,0 +1,8 @@
+package TestAppIndexDefault;
+use strict;
+use warnings;
+use Catalyst;
+
+__PACKAGE__->setup;
+
+1;
@@ -0,0 +1,24 @@
+package TestAppMatchSingleArg::Controller::Root;
+
+use strict;
+use warnings;
+use base 'Catalyst::Controller';
+
+__PACKAGE__->config->{namespace} = '';
+
+sub match_single : Path Args(1) {
+    my ($self, $c) = @_;
+    $c->res->body('Path Args(1)');
+}
+
+sub match_other : Path {
+    my ($self, $c) = @_;
+    $c->res->body('Path');
+}
+
+sub match_two : Path Args(2) {
+    my ($self, $c) = @_;
+    $c->res->body('Path Args(2)');
+}
+
+1;
@@ -0,0 +1,8 @@
+package TestAppMatchSingleArg;
+use strict;
+use warnings;
+use Catalyst;
+
+__PACKAGE__->setup;
+
+1;
@@ -0,0 +1,6 @@
+package TestAppMetaCompat::Controller::Base;
+
+use strict;
+use base qw/Catalyst::Controller/;
+
+1;
@@ -0,0 +1,8 @@
+package TestAppMetaCompat::Controller::Books;
+
+use strict;
+use base qw/TestAppMetaCompat::Controller::Base/;
+
+sub edit : Local {}
+
+1;
@@ -0,0 +1,8 @@
+package TestAppMetaCompat;
+use base qw/Catalyst/;
+
+__PACKAGE__->config(name => __PACKAGE__);
+__PACKAGE__->setup;
+
+1;
+
@@ -0,0 +1,5 @@
+package TestAppNonMooseController::Controller::Foo;
+use base qw/TestAppNonMooseController::ControllerBase/;
+
+1;
+
@@ -0,0 +1,5 @@
+package TestAppNonMooseController::ControllerBase;
+use base qw/Catalyst::Controller/;
+
+1;
+
@@ -0,0 +1,8 @@
+package TestAppNonMooseController;
+use base qw/Catalyst/;
+use Catalyst;
+
+__PACKAGE__->setup;
+
+1;
+
@@ -0,0 +1,41 @@
+package TestAppOnDemand::Controller::Body;
+
+use strict;
+use base 'Catalyst::Controller';
+
+use Data::Dump ();
+
+sub body_params : Local {
+    my ( $self, $c ) = @_;
+
+    $c->res->body( Data::Dump::dump( $c->req->body_parameters ) );
+}
+
+sub query_params : Local {
+    my ( $self, $c ) = @_;
+
+    $c->res->body( Data::Dump::dump( $c->req->query_parameters ) );
+}
+
+sub params : Local {
+    my ( $self, $c ) = @_;
+
+    $c->res->body( Data::Dump::dump( $c->req->parameters ) );
+}
+
+sub read : Local {
+    my ( $self, $c ) = @_;
+    
+    # read some data
+    my @chunks;
+    
+    while ( my $data = $c->read( 10_000 ) ) {
+        push @chunks, $data;
+    }
+
+    $c->res->content_type( 'text/plain');
+    
+    $c->res->body( join ( '|', map { length $_ } @chunks ) );
+}
+
+1;
@@ -0,0 +1,20 @@
+package TestAppOnDemand;
+
+use strict;
+use Catalyst qw/
+    Test::Errors 
+    Test::Headers 
+/;
+use Catalyst::Utils;
+
+our $VERSION = '0.01';
+
+__PACKAGE__->config(
+    name            => __PACKAGE__,
+    root            => '/some/dir',
+    parse_on_demand => 1,
+);
+
+__PACKAGE__->setup;
+
+1;
@@ -0,0 +1,34 @@
+package TestAppOneView::Controller::Root;
+
+use base 'Catalyst::Controller';
+use Scalar::Util ();
+
+__PACKAGE__->config->{namespace} = '';
+
+sub view_no_args : Local {
+    my ( $self, $c ) = @_;
+
+    my $v = $c->view;
+
+    $c->res->body(Scalar::Util::blessed($v));
+}
+
+sub view_by_name : Local {
+    my ( $self, $c ) = @_;
+
+    my $v = $c->view($c->req->param('view'));
+
+    $c->res->body(Scalar::Util::blessed($v));
+}
+
+sub view_by_regex : Local {
+    my ( $self, $c ) = @_;
+
+    my $v_name = $c->req->param('view');
+
+    my ($v) = $c->view(qr/$v_name/);
+
+    $c->res->body(Scalar::Util::blessed($v));
+}
+
+1;
@@ -0,0 +1,13 @@
+package TestAppOneView::View::Dummy;
+
+use base 'Catalyst::View';
+
+sub COMPONENT {
+    bless {}, 'AClass'
+}
+
+package AClass;
+
+use base 'Catalyst::View';
+
+1;
@@ -0,0 +1,8 @@
+package TestAppOneView;
+use strict;
+use warnings;
+use Catalyst;
+
+__PACKAGE__->setup;
+
+1;
@@ -0,0 +1,28 @@
+use strict;
+use warnings;
+
+package TestAppPathBug;
+use strict;
+use warnings;
+use Catalyst;
+
+our $VERSION = '0.01';
+
+__PACKAGE__->config( name => 'TestAppPathBug', root => '/some/dir' );
+
+__PACKAGE__->log(TestAppPathBug::Log->new);
+__PACKAGE__->setup;
+
+sub foo : Path {
+    my ( $self, $c ) = @_;
+    $c->res->body( 'This is the foo method.' );
+}
+
+package TestAppPathBug::Log;
+use strict;
+use warnings;
+use base qw/Catalyst::Log/;
+
+sub warn {}
+
+1;
@@ -0,0 +1,12 @@
+package TestAppPluginWithConstructor::Controller::Root;
+
+use base 'Catalyst::Controller';
+
+__PACKAGE__->config->{namespace} = '';
+
+sub foo : Local {
+    my ($self, $c) = @_;
+    $c->res->body('foo');
+}
+
+1;
@@ -0,0 +1,21 @@
+# See t/plugin_new_method_backcompat.t
+package TestAppPluginWithConstructor;
+use Test::More;
+use Test::Exception;
+use Catalyst qw/+TestPluginWithConstructor/;
+use Moose;
+extends qw/Catalyst/;
+
+__PACKAGE__->setup;
+our $MODIFIER_FIRED = 0;
+
+lives_ok {
+    before 'dispatch' => sub { $MODIFIER_FIRED = 1 }
+} 'Can apply method modifier';
+no Moose;
+
+our $IS_IMMUTABLE_YET = __PACKAGE__->meta->is_immutable;
+ok !$IS_IMMUTABLE_YET, 'I am not immutable yet';
+
+1;
+
@@ -0,0 +1,19 @@
+package TestAppShowInternalActions::Controller::Root;
+use Moose;
+use namespace::autoclean;
+
+BEGIN { extends 'Catalyst::Controller' }
+
+__PACKAGE__->config(namespace => '');
+
+sub index :Path :Args(0) {
+    my ( $self, $c ) = @_;
+
+    $c->response->body( 'hello world' );
+}
+
+sub end : Action {}
+
+__PACKAGE__->meta->make_immutable;
+
+1;
@@ -0,0 +1,20 @@
+package TestAppShowInternalActions;
+use Moose;
+use namespace::autoclean;
+
+use Catalyst::Runtime 5.80;
+
+use Catalyst qw/ -Debug /; # Debug must remain on for
+                           # t/live_show_internal_actions_warnings.t
+
+extends 'Catalyst';
+
+__PACKAGE__->config(
+    name => 'TestAppShowInternalActions',
+    disable_component_resolution_regex_fallback => 1,
+    show_internal_actions => 1,
+);
+
+__PACKAGE__->setup();
+
+1;
@@ -0,0 +1,16 @@
+package TestAppStats::Controller::Root;
+use strict;
+use warnings;
+use base 'Catalyst::Controller';
+
+__PACKAGE__->config->{namespace} = '';
+
+# Return log messages from previous request
+sub default : Private {
+    my ( $self, $c ) = @_;
+    $c->stats->profile("test");
+    $c->res->body(join("\n", @TestAppStats::log_messages));
+    @TestAppStats::log_messages = ();
+}
+
+1;
@@ -0,0 +1,26 @@
+use strict;
+use warnings;
+
+package TestAppStats;
+
+use Catalyst qw/
+    -Stats=1
+/;
+
+our $VERSION = '0.01';
+our @log_messages;
+
+__PACKAGE__->config( name => 'TestAppStats', root => '/some/dir' );
+
+__PACKAGE__->log(TestAppStats::Log->new);
+
+__PACKAGE__->setup;
+
+package TestAppStats::Log;
+use base qw/Catalyst::Log/;
+
+sub info { push(@TestAppStats::log_messages, @_); }
+sub debug { push(@TestAppStats::log_messages, @_); }
+
+1;
+
@@ -0,0 +1,14 @@
+package TestAppToTestScripts;
+use strict;
+use warnings;
+use Carp;
+
+our @RUN_ARGS;
+
+sub run {
+    @RUN_ARGS = @_;
+    1; # Does this work?
+}
+
+1;
+
@@ -0,0 +1,22 @@
+package TestApp;
+
+use strict;
+use warnings;
+
+use Catalyst::Runtime 5.70;
+
+use base qw/Catalyst/;
+
+use Catalyst;
+
+__PACKAGE__->setup();
+
+sub _test {
+    my $self = shift;
+    $self->_method_which_does_not_exist;
+}
+
+__PACKAGE__->_test;
+
+1;
+
@@ -0,0 +1,17 @@
+package TestAppWithMeta::Controller::Root;
+use base qw/Catalyst::Controller/; # N.B. Do not convert to Moose, so we do not
+                                   #      have a metaclass instance!
+
+__PACKAGE__->config( namespace => '' );
+
+no warnings 'redefine';
+sub meta { 'fnar' }
+use warnings 'redefine';
+
+sub default : Private {
+    my ($self, $c) = @_;
+    $c->res->body($self->meta);
+}
+
+1;
+
@@ -0,0 +1,13 @@
+package TestAppWithMeta;
+use strict;
+use warnings;
+use Catalyst;
+
+no warnings 'redefine';
+sub meta {}
+use warnings 'redefine';
+
+__PACKAGE__->setup;
+
+1;
+
@@ -0,0 +1,17 @@
+# See t/plugin_new_method_backcompat.t
+package Class::Accessor::Fast;
+use strict;
+use warnings;
+
+sub new {
+    my $class = shift;
+    return bless $_[0], $class;
+}
+
+package TestPluginWithConstructor;
+use strict;
+use warnings;
+use base qw/Class::Accessor::Fast/;
+
+1;
+
@@ -1,110 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 28 * $iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    {
-        ok( my $response = request('http://localhost/action_action_one'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action_action_one', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Action',
-            'Test Class'
-        );
-        is( $response->header('X-Action'), 'works' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action_action_two'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action_action_two', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Action',
-            'Test Class'
-        );
-        is( $response->header('X-Action-After'), 'awesome' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok(
-            my $response =
-              request('http://localhost/action_action_three/one/two'),
-            'Request'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action_action_three', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Action',
-            'Test Class'
-        );
-        is( $response->header('X-TestAppActionTestBefore'), 'one' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action_action_four'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action_action_four', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Action',
-            'Test Class'
-        );
-        is( $response->header('X-TestAppActionTestMyAction'), 'MyAction works' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-}
@@ -1,136 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 18*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-    
-    # new dispatcher:
-    # 11 wallclock secs (10.14 usr +  0.20 sys = 10.34 CPU) @ 15.18/s (n=157)
-    # old dispatcher (r1486):
-    # 11 wallclock secs (10.34 usr +  0.20 sys = 10.54 CPU) @ 13.76/s (n=145)
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-    
-sub run_tests {
-    # test auto + local method
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Auto->begin
-          TestApp::Controller::Action::Auto->auto
-          TestApp::Controller::Action::Auto->one
-          TestApp->end
-        ];
-    
-        my $expected = join( ", ", @expected );
-    
-        ok( my $response = request('http://localhost/action/auto/one'), 'auto + local' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, 'one', 'Content OK' );
-    }
-    
-    # test auto + default
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Auto->begin
-          TestApp::Controller::Action::Auto->auto
-          TestApp::Controller::Action::Auto->default
-          TestApp->end
-        ];
-    
-        my $expected = join( ", ", @expected );
-    
-        ok( my $response = request('http://localhost/action/auto/anything'), 'auto + default' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, 'default', 'Content OK' );
-    }
-    
-    # test auto + auto + local
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Auto::Deep->begin
-          TestApp::Controller::Action::Auto->auto
-          TestApp::Controller::Action::Auto::Deep->auto
-          TestApp::Controller::Action::Auto::Deep->one
-          TestApp->end
-        ];
-    
-        my $expected = join( ", ", @expected );
-    
-        ok( my $response = request('http://localhost/action/auto/deep/one'), 'auto + auto + local' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, 'deep one', 'Content OK' );
-    }
-    
-    # test auto + auto + default
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Auto::Deep->begin
-          TestApp::Controller::Action::Auto->auto
-          TestApp::Controller::Action::Auto::Deep->auto
-          TestApp::Controller::Action::Auto::Deep->default
-          TestApp->end
-        ];
-    
-        my $expected = join( ", ", @expected );
-    
-        ok( my $response = request('http://localhost/action/auto/deep/anything'), 'auto + auto + default' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, 'deep default', 'Content OK' );
-    }
-    
-    # test auto + failing auto + local + end
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Auto::Abort->begin
-          TestApp::Controller::Action::Auto->auto
-          TestApp::Controller::Action::Auto::Abort->auto
-          TestApp::Controller::Action::Auto::Abort->end
-        ];
-    
-        my $expected = join( ", ", @expected );
-    
-        ok( my $response = request('http://localhost/action/auto/abort/one'), 'auto + failing auto + local' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, 'abort end', 'Content OK' );
-    }
-    
-    # test auto + default (bug on invocation of default twice)
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Auto::Default->begin
-          TestApp::Controller::Action::Auto->auto
-          TestApp::Controller::Action::Auto::Default->auto
-          TestApp::Controller::Action::Auto::Default->default
-          TestApp::Controller::Action::Auto::Default->end
-        ];
-    
-        my $expected = join( ", ", @expected );
-    
-        ok( my $response = request('http://localhost/action/auto/default/moose'), 'auto + default' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, 'default (auto: 1)', 'Content OK' );
-    }
-}
@@ -1,53 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 7*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Begin->begin
-          TestApp::Controller::Action::Begin->default
-          TestApp::View::Dump::Request->process
-          TestApp->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/action/begin'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Begin',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        like( $response->content, qr/'Catalyst::Request'/,
-            'Content is a serialized Catalyst::Request' );
-    }
-}
@@ -1,831 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 118*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests($_);
-    }
-}
-
-sub run_tests {
-    my ($run_number) = @_;
-
-    #
-    #   This is a simple test where the parent and child actions are
-    #   within the same controller.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->foo
-          TestApp::Controller::Action::Chained->endpoint
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/foo/1/end/2'), 'chained + local endpoint' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   This makes sure the above isn't found if the argument for the
-    #   end action isn't supplied.
-    #
-    {
-        my $expected = undef;
-
-        ok( my $response = request('http://localhost/chained/foo/1/end'), 
-            'chained + local endpoint; missing last argument' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->code, 500, 'Status OK' );
-    }
-
-    #
-    #   Tests the case when the child action is placed in a subcontroller.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->foo
-          TestApp::Controller::Action::Chained::Foo->spoon
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/foo/1/spoon'), 'chained + subcontroller endpoint' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; ', 'Content OK' );
-    }
-
-    #
-    #   Tests if the relative specification (e.g.: Chained('bar') ) works
-    #   as expected.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->bar
-          TestApp::Controller::Action::Chained->finale
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/bar/1/spoon'), 'chained + relative endpoint' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '; 1, spoon', 'Content OK' );
-    }
-
-    #
-    #   Just a test for multiple arguments.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->foo2
-          TestApp::Controller::Action::Chained->endpoint2
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/foo2/10/20/end2/15/25'), 
-            'chained + local (2 args each)' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '10, 20; 15, 25', 'Content OK' );
-    }
-
-    #
-    #   The first three-chain test tries to call the action with :Args(1)
-    #   specification. There's also a one action with a :CaptureArgs(1)
-    #   attribute, that should not be dispatched to.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->one_end
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/one/23'),
-            'three-chain (only first)' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '; 23', 'Content OK' );
-    }
-
-    #
-    #   This is the second three-chain test, it goes for the action that
-    #   handles "/one/$cap/two/$arg1/$arg2" paths. Should be the two action
-    #   having :Args(2), not the one having :CaptureArgs(2).
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->one
-          TestApp::Controller::Action::Chained->two_end
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/one/23/two/23/46'),
-            'three-chain (up to second)' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '23; 23, 46', 'Content OK' );
-    }
-
-    #
-    #   Last of the three-chain tests. Has no concurrent action with :CaptureArgs
-    #   and is more thought to simply test the chain as a whole and the 'two'
-    #   action specifying :CaptureArgs.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->one
-          TestApp::Controller::Action::Chained->two
-          TestApp::Controller::Action::Chained->three_end
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/one/23/two/23/46/three/1/2/3'),
-            'three-chain (all three)' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '23, 23, 46; 1, 2, 3', 'Content OK' );
-    }
-
-    #
-    #   Tests dispatching on number of arguments for :Args. This should be
-    #   dispatched to the action expecting one argument.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->multi1
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/multi/23'),
-            'multi-action (one arg)' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '; 23', 'Content OK' );
-    }
-
-    #
-    #   Belongs to the former test and goes for the action expecting two arguments.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->multi2
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/multi/23/46'),
-            'multi-action (two args)' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '; 23, 46', 'Content OK' );
-    }
-
-    #
-    #   Dispatching on argument count again, this time we provide too many
-    #   arguments, so dispatching should fail.
-    #
-    {
-        my $expected = undef;
-
-        ok( my $response = request('http://localhost/chained/multi/23/46/67'),
-            'multi-action (three args, should lead to error)' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->code, 500, 'Status OK' );
-    }
-
-    #
-    #   This tests the case when an action says it's the child of an action in
-    #   a subcontroller.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained::Foo->higher_root
-          TestApp::Controller::Action::Chained->higher_root
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/higher_root/23/bar/11'),
-            'root higher than child' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '23; 11', 'Content OK' );
-    }
-
-    #
-    #   Just a more complex version of the former test. It tests if a controller ->
-    #   subcontroller -> controller dispatch works.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->pcp1
-          TestApp::Controller::Action::Chained::Foo->pcp2
-          TestApp::Controller::Action::Chained->pcp3
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/pcp1/1/pcp2/2/pcp3/3'),
-            'parent -> child -> parent' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1, 2; 3', 'Content OK' );
-    }
-
-    #
-    #   Tests dispatch on capture number. This test is for a one capture action.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->multi_cap1
-          TestApp::Controller::Action::Chained->multi_cap_end1
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/multi_cap/1/baz'),
-            'dispatch on capture num 1' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; ', 'Content OK' );
-    }
-
-    #
-    #   Belongs to the former test. This one goes for the action expecting two
-    #   captures.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->multi_cap2
-          TestApp::Controller::Action::Chained->multi_cap_end2
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/multi_cap/1/2/baz'),
-            'dispatch on capture num 2' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1, 2; ', 'Content OK' );
-    }
-
-    #
-    #   Tests the priority of a slurpy arguments action (with :Args) against
-    #   two actions chained together. The two actions should win.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->priority_a2
-          TestApp::Controller::Action::Chained->priority_a2_end
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/priority_a/1/end/2'),
-            'priority - slurpy args vs. parent/child' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   This belongs to the former test but tests if two chained actions have
-    #   priority over an action with the exact arguments.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->priority_b2
-          TestApp::Controller::Action::Chained->priority_b2_end
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/priority_b/1/end/2'),
-            'priority - fixed args vs. parent/child' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   This belongs to the former test but tests if two chained actions have
-    #   priority over an action with one child action not having the Args() attr set.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->priority_c1
-          TestApp::Controller::Action::Chained->priority_c2_xyz
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/priority_c/1/xyz/'),
-            'priority - no Args() order mismatch' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; ', 'Content OK' );
-    }
-
-    #
-    #   Test dispatching between two controllers that are on the same level and
-    #   therefor have no parent/child relationship.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained::Bar->cross1
-          TestApp::Controller::Action::Chained::Foo->cross2
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/cross/1/end/2'),
-            'cross controller w/o par/child relation' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   This is for testing if the arguments got passed to the actions 
-    #   correctly.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained::PassedArgs->first
-          TestApp::Controller::Action::Chained::PassedArgs->second
-          TestApp::Controller::Action::Chained::PassedArgs->third
-          TestApp::Controller::Action::Chained::PassedArgs->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/passedargs/a/1/b/2/c/3'),
-            'Correct arguments passed to actions' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2; 3', 'Content OK' );
-    }
-
-    #
-    #   The :Args attribute is optional, we check the action not specifying
-    #   it with these tests.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->opt_args
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/opt_args/1/2/3'),
-            'Optional :Args attribute working' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '; 1, 2, 3', 'Content OK' );
-    }
-
-    #
-    #   Tests for optional PathPart attribute.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->opt_pp_start
-          TestApp::Controller::Action::Chained->opt_pathpart
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/optpp/1/opt_pathpart/2'),
-            'Optional :PathName attribute working' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   Tests for optional PathPart *and* Args attributes.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->opt_all_start
-          TestApp::Controller::Action::Chained->oa
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/optall/1/oa/2/3'),
-            'Optional :PathName *and* :Args attributes working' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2, 3', 'Content OK' );
-    }
-
-    #
-    #   Test if :Chained is the same as :Chained('/')
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->rootdef
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/rootdef/23'),
-            ":Chained is the same as :Chained('/')" );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '; 23', 'Content OK' );
-    }
-
-    #
-    #   Test if :Chained('.') is working
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->parentchain
-          TestApp::Controller::Action::Chained::ParentChain->child
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/parentchain/1/child/2'),
-            ":Chained('.') chains to parent controller action" );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   Test behaviour of auto actions returning '1' for the chain.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained::Auto->auto
-          TestApp::Controller::Action::Chained::Auto::Foo->auto
-          TestApp::Controller::Action::Chained::Auto->foo
-          TestApp::Controller::Action::Chained::Auto::Foo->fooend
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/autochain1/1/fooend/2'),
-            "Behaviour when auto returns 1 correct" );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   Test behaviour of auto actions returning '0' for the chain.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained::Auto->auto
-          TestApp::Controller::Action::Chained::Auto::Bar->auto
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/autochain2/1/barend/2'),
-            "Behaviour when auto returns 0 correct" );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   Test what auto actions are run when namespaces are changed
-    #   horizontally.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained::Auto->auto
-          TestApp::Controller::Action::Chained::Auto::Foo->auto
-          TestApp::Controller::Action::Chained::Auto::Bar->crossloose
-          TestApp::Controller::Action::Chained::Auto::Foo->crossend
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/auto_cross/1/crossend/2'),
-            "Correct auto actions are run on cross controller dispatch" );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   Test forwarding from auto action in chain dispatch.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained::Auto->auto
-          TestApp::Controller::Action::Chained::Auto::Forward->auto
-          TestApp::Controller::Action::Chained::Auto->fw3
-          TestApp::Controller::Action::Chained::Auto->fw1
-          TestApp::Controller::Action::Chained::Auto::Forward->forwardend
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/auto_forward/1/forwardend/2'),
-            "Forwarding out of auto in chain" );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   Detaching out of the auto action of a chain.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained::Auto->auto
-          TestApp::Controller::Action::Chained::Auto::Detach->auto
-          TestApp::Controller::Action::Chained::Auto->fw3
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/auto_detach/1/detachend/2'),
-            "Detaching out of auto in chain" );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   Test forwarding from auto action in chain dispatch.
-    #
-    {
-        my $expected = undef;
-
-        ok( my $response = request('http://localhost/chained/loose/23'),
-            "Loose end is not callable" );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->code, 500, 'Status OK' );
-    }
-
-    #
-    #   Test forwarding out of a chain.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->chain_fw_a
-          TestApp::Controller::Action::Chained->fw_dt_target
-          TestApp::Controller::Action::Chained->chain_fw_b
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/chain_fw/1/end/2'),
-            "Forwarding out a chain" );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   Test detaching out of a chain.
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->chain_dt_a
-          TestApp::Controller::Action::Chained->fw_dt_target
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/chain_dt/1/end/2'),
-            "Forwarding out a chain" );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '1; 2', 'Content OK' );
-    }
-
-    #
-    #   Tests that an uri_for to a chained root index action
-    #   returns the right value.
-    #
-    {
-        ok( my $response = request(
-            'http://localhost/action/chained/to_root' ),
-            'uri_for with chained root action as arg' );
-        like( $response->content,
-            qr(URI:https?://[^/]+/),
-            'Correct URI generated' );
-    }
-
-    #
-    #   Test interception of recursive chains. This test was added because at
-    #   one point during the :Chained development, Catalyst used to hang on
-    #   recursive chains.
-    #
-    {
-        eval { require 'TestAppChainedRecursive.pm' };
-        if ($run_number == 1) {
-            ok( ! $@, "Interception of recursive chains" );
-        }
-        else { pass( "Interception of recursive chains already tested" ) }
-    }
-
-    #
-    #   Test failure of absolute path part arguments.
-    #
-    {
-        eval { require 'TestAppChainedAbsolutePathPart.pm' };
-        if ($run_number == 1) {
-            like( $@, qr(foo/foo),
-                "Usage of absolute path part argument emits error" );
-        }
-        else { pass( "Error on absolute path part arguments already tested" ) }
-    }
-
-    #
-    #   Test chained actions in the root controller
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained::Root->rootsub
-          TestApp::Controller::Action::Chained::Root->endpointsub
-          TestApp->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/rootsub/1/endpointsub/2'), 'chained in root namespace' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '', 'Content OK' );
-    }
-
-    #
-    #   Complex path with multiple empty pathparts
-    #
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Chained->begin
-          TestApp::Controller::Action::Chained->mult_nopp_base
-          TestApp::Controller::Action::Chained->mult_nopp_all
-          TestApp::Controller::Action::Chained->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/chained/mult_nopp'),
-            "Complex path with multiple empty pathparts" );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, '; ', 'Content OK' );
-    }
-
-	#
-	#	Higher Args() hiding more specific CaptureArgs chains sections
-	#
-	{
-		my @expected = qw[
-		  	TestApp::Controller::Action::Chained->begin
-		  	TestApp::Controller::Action::Chained->cc_base
-		  	TestApp::Controller::Action::Chained->cc_link
-		  	TestApp::Controller::Action::Chained->cc_anchor
-		  	TestApp::Controller::Action::Chained->end
-			];
-
-		my $expected = join ', ', @expected;
-
-		ok( my $response = request('http://localhost/chained/choose_capture/anchor.html'),
-			'Choose between an early Args() and a later more ideal chain' );
-		is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions');
-		is( $response->content => '; ', 'Content OK' );
-	}
-
-	#
-	#	Less specific chain not being seen correctly due to earlier looser capture
-	#
-	{
-		my @expected = qw[
-		  	TestApp::Controller::Action::Chained->begin
-		  	TestApp::Controller::Action::Chained->cc_base
-		  	TestApp::Controller::Action::Chained->cc_b
-		  	TestApp::Controller::Action::Chained->cc_b_link
-		  	TestApp::Controller::Action::Chained->cc_b_anchor
-		  	TestApp::Controller::Action::Chained->end
-			];
-
-		my $expected = join ', ', @expected;
-
-		ok( my $response = request('http://localhost/chained/choose_capture/b/a/anchor.html'),
-			'Choose between a more specific chain and an earlier looser one' );
-		is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions');
-		is( $response->content => 'a; ', 'Content OK' );
-	}
-
-	#
-	#	Check we get the looser one when it's the correct match
-	#
-	{
-		my @expected = qw[
-		  	TestApp::Controller::Action::Chained->begin
-		  	TestApp::Controller::Action::Chained->cc_base
-		  	TestApp::Controller::Action::Chained->cc_a
-		  	TestApp::Controller::Action::Chained->cc_a_link
-		  	TestApp::Controller::Action::Chained->cc_a_anchor
-		  	TestApp::Controller::Action::Chained->end
-			];
-
-		my $expected = join ', ', @expected;
-
-		ok( my $response = request('http://localhost/chained/choose_capture/a/a/anchor.html'),
-			'Choose between a more specific chain and an earlier looser one' );
-		is( $response->header('X-Catalyst-Executed') => $expected, 'Executed actions');
-		is( $response->content => 'a; anchor.html', 'Content OK' );
-	}
-
-}
@@ -1,96 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 16 * $iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Default->begin
-          TestApp::Controller::Action::Default->default
-          TestApp::View::Dump::Request->process
-          TestApp->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/action/default'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Default',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-
-        ok( $response = request('http://localhost/foo/bar/action'), 'Request' );
-        is( $response->code, 500, 'Invalid URI returned 500' );
-    }
-
-    # test that args are passed properly to default
-    {
-        my $creq;
-        my $expected = [qw/action default arg1 arg2/];
-
-        ok( my $response = request('http://localhost/action/default/arg1/arg2'),
-            'Request' );
-        ok(
-            eval '$creq = ' . $response->content,
-            'Unserialize Catalyst::Request'
-        );
-        is_deeply( $creq->{arguments}, $expected, 'Arguments ok' );
-    }
-    
-    
-    # Test that /foo and /foo/ both do the same thing
-    {
-        my @expected = qw[
-          TestApp::Controller::Action->begin
-          TestApp::Controller::Action->default
-          TestApp->end
-        ];
-        
-        my $expected = join( ", ", @expected );
-        
-        ok( my $response = request('http://localhost/action'), 'Request' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 
-            'Executed actions for /action'
-        );
-        
-        ok( $response = request('http://localhost/action/'), 'Request' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 
-            'Executed actions for /action/'
-        );
-    }   
-}
@@ -1,100 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 18*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Detach->begin
-          TestApp::Controller::Action::Detach->one
-          TestApp::Controller::Action::Detach->two
-          TestApp::View::Dump::Request->process
-          TestApp->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        # Test detach to chain of actions.
-        ok( my $response = request('http://localhost/action/detach/one'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/detach/one', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Detach',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-    }
-
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Detach->begin
-          TestApp::Controller::Action::Detach->path
-          TestApp::Controller::Action::Detach->two
-          TestApp::View::Dump::Request->process
-          TestApp->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        # Test detach to chain of actions.
-        ok( my $response = request('http://localhost/action/detach/path'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/detach/path', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Detach',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-    }
-
-    {
-        ok(
-            my $response =
-              request('http://localhost/action/detach/with_args/old'),
-            'Request with args'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content, 'new' );
-    }
-
-    {
-        ok(
-            my $response = request(
-                'http://localhost/action/detach/with_method_and_args/old'),
-            'Request with args and method'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content, 'new' );
-    }
-}
@@ -1,54 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 7*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::End->begin
-          TestApp::Controller::Action::End->default
-          TestApp::View::Dump::Request->process
-          TestApp::Controller::Action::End->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/action/end'), 'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::End',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-}
@@ -1,238 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 47 * $iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Forward->begin
-          TestApp::Controller::Action::Forward->one
-          TestApp::Controller::Action::Forward->two
-          TestApp::Controller::Action::Forward->three
-          TestApp::Controller::Action::Forward->four
-          TestApp::Controller::Action::Forward->five
-          TestApp::View::Dump::Request->process
-          TestApp->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        # Test forward to global private action
-        ok( my $response = request('http://localhost/action/forward/global'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/forward/global', 'Main Class Action' );
-
-        # Test forward to chain of actions.
-        ok( $response = request('http://localhost/action/forward/one'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/forward/one', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Forward',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Forward->begin
-          TestApp::Controller::Action::Forward->jojo
-          TestApp::Controller::Action::Forward->one
-          TestApp::Controller::Action::Forward->two
-          TestApp::Controller::Action::Forward->three
-          TestApp::Controller::Action::Forward->four
-          TestApp::Controller::Action::Forward->five
-          TestApp::View::Dump::Request->process
-          TestApp::Controller::Action::Forward->three
-          TestApp::Controller::Action::Forward->four
-          TestApp::Controller::Action::Forward->five
-          TestApp::View::Dump::Request->process
-          TestApp->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/action/forward/jojo'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/forward/jojo', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Forward',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok(
-            my $response =
-              request('http://localhost/action/forward/with_args/old'),
-            'Request with args'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content, 'old' );
-    }
-
-    {
-        ok(
-            my $response = request(
-                'http://localhost/action/forward/with_method_and_args/old'),
-            'Request with args and method'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content, 'old' );
-    }
-
-    # test forward with embedded args
-    {
-        ok(
-            my $response =
-              request('http://localhost/action/forward/args_embed_relative'),
-            'Request'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content, 'ok' );
-    }
-
-    {
-        ok(
-            my $response =
-              request('http://localhost/action/forward/args_embed_absolute'),
-            'Request'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content, 'ok' );
-    }
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::TestRelative->begin
-          TestApp::Controller::Action::TestRelative->relative
-          TestApp::Controller::Action::Forward->one
-          TestApp::Controller::Action::Forward->two
-          TestApp::Controller::Action::Forward->three
-          TestApp::Controller::Action::Forward->four
-          TestApp::Controller::Action::Forward->five
-          TestApp::View::Dump::Request->process
-          TestApp->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        # Test forward to chain of actions.
-        ok( my $response = request('http://localhost/action/relative/relative'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/relative/relative', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::TestRelative',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::TestRelative->begin
-          TestApp::Controller::Action::TestRelative->relative_two
-          TestApp::Controller::Action::Forward->one
-          TestApp::Controller::Action::Forward->two
-          TestApp::Controller::Action::Forward->three
-          TestApp::Controller::Action::Forward->four
-          TestApp::Controller::Action::Forward->five
-          TestApp::View::Dump::Request->process
-          TestApp->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        # Test forward to chain of actions.
-        ok(
-            my $response =
-              request('http://localhost/action/relative/relative_two'),
-            'Request'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is(
-            $response->header('X-Catalyst-Action'),
-            'action/relative/relative_two',
-            'Test Action'
-        );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::TestRelative',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    # test class forwards
-    {
-        ok(
-            my $response = request(
-                'http://localhost/action/forward/class_forward_test_action'),
-            'Request'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->header('X-Class-Forward-Test-Method'), 1,
-            'Test Method' );
-    }
-
-}
@@ -1,83 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 18*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    {
-        ok( my $response = request('http://localhost/action_global_one'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action_global_one', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Global',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action_global_two'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action_global_two', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Global',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action_global_three'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action_global_three', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Global',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-}
@@ -1,100 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 20*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    # test root index
-    {
-        my @expected = qw[
-          TestApp->index
-          TestApp->end
-        ];
-    
-        my $expected = join( ", ", @expected );
-        ok( my $response = request('http://localhost/'), 'root index' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, 'root index', 'root index ok' );
-        
-        ok( $response = request('http://localhost'), 'root index no slash' );
-        is( $response->content, 'root index', 'root index no slash ok' );
-    }
-    
-    # test first-level controller index
-    {
-        my @expected = qw[
-          TestApp::Controller::Index->index
-          TestApp->end
-        ];
-    
-        my $expected = join( ", ", @expected );
-        
-        ok( my $response = request('http://localhost/index/'), 'first-level controller index' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, 'Index index', 'first-level controller index ok' );
-        
-        ok( $response = request('http://localhost/index'), 'first-level controller index no slash' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, 'Index index', 'first-level controller index no slash ok' );        
-    }    
-    
-    # test second-level controller index
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Index->begin
-          TestApp::Controller::Action::Index->index
-          TestApp->end
-        ];
-    
-        my $expected = join( ", ", @expected );
-        
-        ok( my $response = request('http://localhost/action/index/'), 'second-level controller index' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, 'Action-Index index', 'second-level controller index ok' );
-        
-        ok( $response = request('http://localhost/action/index'), 'second-level controller index no slash' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, 'Action-Index index', 'second-level controller index no slash ok' );        
-    }
-    
-    # test controller default when index is present
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Index->begin
-          TestApp::Controller::Action::Index->default
-          TestApp->end
-        ];
-    
-        my $expected = join( ", ", @expected );
-        
-        ok( my $response = request('http://localhost/action/index/foo'), 'default with index' );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        is( $response->content, "Error - TestApp::Controller::Action\n", 'default with index ok' );
-    }
-}
@@ -1,119 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 21*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Inheritance->begin
-          TestApp::Controller::Action::Inheritance->auto
-          TestApp::Controller::Action::Inheritance->default
-          TestApp::View::Dump::Request->process
-          TestApp::Controller::Action::Inheritance->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/action/inheritance'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Inheritance',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Inheritance::A->begin
-          TestApp::Controller::Action::Inheritance->auto
-          TestApp::Controller::Action::Inheritance::A->auto
-          TestApp::Controller::Action::Inheritance::A->default
-          TestApp::View::Dump::Request->process
-          TestApp::Controller::Action::Inheritance::A->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/action/inheritance/a'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Inheritance::A',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        my @expected = qw[
-          TestApp::Controller::Action::Inheritance::A::B->begin
-          TestApp::Controller::Action::Inheritance->auto
-          TestApp::Controller::Action::Inheritance::A->auto
-          TestApp::Controller::Action::Inheritance::A::B->auto
-          TestApp::Controller::Action::Inheritance::A::B->default
-          TestApp::View::Dump::Request->process
-          TestApp::Controller::Action::Inheritance::A::B->end
-        ];
-
-        my $expected = join( ", ", @expected );
-
-        ok( my $response = request('http://localhost/action/inheritance/a/b'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'), 'default', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Inheritance::A::B',
-            'Test Class'
-        );
-        is( $response->header('X-Catalyst-Executed'),
-            $expected, 'Executed actions' );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-}
@@ -1,138 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 32*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    {
-        ok( my $response = request('http://localhost/action/local/one'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/local/one', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Local',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/local/two/1/2'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/local/two', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Local',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-         ok( my $response = request('http://localhost/action/local/two'),
-               'Request' );
-         ok( !$response->is_success, 'Request with wrong number of args failed' );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/local/three'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/local/three', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Local',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok(
-            my $response =
-              request('http://localhost/action/local/four/five/six'),
-            'Request'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/local/four/five/six', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Local',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    SKIP:
-    { 
-        if ( $ENV{CATALYST_SERVER} ) {
-            skip "tests for %2F on remote server", 6;
-        }
-        
-        ok(
-            my $response =
-              request('http://localhost/action/local/one/foo%2Fbar'),
-            'Request'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/local/one', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Local',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr~arguments => \[\s*'foo/bar'\s*\]~,
-            "Parameters don't split on %2F"
-        );
-    }
-}
@@ -1,71 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-my $content = q/foo
-bar
-baz
-/;
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 16*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    # Local
-    {
-        ok(
-            my $response =
-              request('http://localhost/action/multipath/multipath'),
-            'Request'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->content, $content, 'Content is a stream' );
-    }
-
-    # Global
-    {
-        ok( my $response = request('http://localhost/multipath'), 'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->content, $content, 'Content is a stream' );
-    }
-
-    # Path('/multipath1')
-    {
-        ok( my $response = request('http://localhost/multipath1'), 'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->content, $content, 'Content is a stream' );
-    }
-
-    # Path('multipath2')
-    {
-        ok(
-            my $response =
-              request('http://localhost/action/multipath/multipath2'),
-            'Request'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->content, $content, 'Content is a stream' );
-    }
-}
@@ -1,127 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 30*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    {
-        ok(
-            my $response =
-              request('http://localhost/action/path/a%20path%20with%20spaces'),
-            'Request'
-        );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is(
-            $response->header('X-Catalyst-Action'),
-            'action/path/a%20path%20with%20spaces',
-            'Test Action'
-        );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Path',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/path/åäö'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/path/%C3%A5%C3%A4%C3%B6', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Path',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/path/'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/path', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Path',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/path/spaces_near_parens_singleq'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/path/spaces_near_parens_singleq', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Path',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/path/spaces_near_parens_doubleq'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            'action/path/spaces_near_parens_doubleq', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Path',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-}
@@ -1,89 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 24*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    {
-        ok( my $response = request('http://localhost/action/private/one'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Private',
-            'Test Class'
-        );
-        is( $response->content, 'access denied', 'Access' );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/private/two'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Private',
-            'Test Class'
-        );
-        is( $response->content, 'access denied', 'Access' );
-    }
-
-    {
-        ok( my $response = request('http://localhost/three'), 'Request' );
-        ok( $response->is_error, 'Response Server Error 5xx' );
-        is( $response->content_type, 'text/html', 'Response Content-Type' );
-        like(
-            $response->header('X-Catalyst-Error'),
-            qr/^Unknown resource "three"/,
-            'Catalyst Error'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/private/four'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Private',
-            'Test Class'
-        );
-        is( $response->content, 'access denied', 'Access' );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/private/five'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Private',
-            'Test Class'
-        );
-        is( $response->content, 'access denied', 'Access' );
-    }
-}
@@ -1,106 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 28*$iters;
-use Catalyst::Test 'TestApp';
-
-use Catalyst::Request;
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    {
-        ok( my $response = request('http://localhost/action/regexp/10/hello'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            '^action/regexp/(\d+)/(\w+)$', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Regexp',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/regexp/hello/10'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            '^action/regexp/(\w+)/(\d+)$', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Regexp',
-            'Test Class'
-        );
-        like(
-            $response->content,
-            qr/^bless\( .* 'Catalyst::Request' \)$/s,
-            'Content is a serialized Catalyst::Request'
-        );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/regexp/mandatory'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            '^action/regexp/(mandatory)(/optional)?$', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Regexp',
-            'Test Class'
-        );
-        my $content = $response->content;
-        my $req = eval $content; 
-
-        is( scalar @{ $req->captures }, 2, 'number of captures' );
-        is( $req->captures->[ 0 ], 'mandatory', 'mandatory capture' );
-        ok( !defined $req->captures->[ 1 ], 'optional capture' );
-    }
-
-    {
-        ok( my $response = request('http://localhost/action/regexp/mandatory/optional'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->header('X-Catalyst-Action'),
-            '^action/regexp/(mandatory)(/optional)?$', 'Test Action' );
-        is(
-            $response->header('X-Test-Class'),
-            'TestApp::Controller::Action::Regexp',
-            'Test Class'
-        );
-        my $content = $response->content;
-        my $req = eval $content; 
-
-        is( scalar @{ $req->captures }, 2, 'number of captures' );
-        is( $req->captures->[ 0 ], 'mandatory', 'mandatory capture' );
-        is( $req->captures->[ 1 ], '/optional', 'optional capture' );
-    }
-}
@@ -1,72 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1; }
-
-use Test::More tests => 10*$iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    # test direct streaming
-    {
-        ok( my $response = request('http://localhost/streaming'), 'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        
-        SKIP:
-        {
-            if ( $ENV{CATALYST_SERVER} ) {
-                skip "Using remote server", 1;
-            }
-            
-            # XXX: Length should be undef here, but HTTP::Request::AsCGI sets it
-            is( $response->content_length, 12, 'Response Content-Length' );
-        }
-        
-        is( $response->content,, <<'EOF', 'Content is a stream' );
-foo
-bar
-baz
-EOF
-    }
-
-    # test streaming by passing a handle to $c->res->body
-  SKIP:
-    {
-        if ( $ENV{CATALYST_SERVER} ) {
-            skip "Using remote server", 5;
-        }
-
-        my $file = "$FindBin::Bin/01use.t";
-        my $fh = IO::File->new( $file, 'r' );
-        my $buffer;
-        if ( defined $fh ) {
-            $fh->read( $buffer, 1024 );
-            $fh->close;
-        }
-
-        ok( my $response = request('http://localhost/action/streaming/body'),
-            'Request' );
-        ok( $response->is_success, 'Response Successful 2xx' );
-        is( $response->content_type, 'text/plain', 'Response Content-Type' );
-        is( $response->content_length, -s $file, 'Response Content-Length' );
-        is( $response->content, $buffer, 'Content is read from filehandle' );
-    }
-}
@@ -1,98 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use URI::Escape;
-
-our @paths;
-our $iters;
-
-BEGIN { $iters = $ENV{CAT_BENCH_ITERS} || 1;
-
-    # add special paths to test here
-    @paths = (
-        # all reserved in uri's
-        qw~ : / ? [ ] @ ! $ & ' ( ) * + ; = ~, ',' , '#',
-
-        # unreserved
-        'a'..'z','A'..'Z',0..9,qw( - . _ ~ ),
-        " ",
-
-        # just to test %2F/%
-        [ qw~ / / ~ ],
-
-        # testing %25/%25
-        [ qw~ % % ~ ],
-    );
-}
-
-use Test::More tests => 6*@paths * $iters;
-use Catalyst::Test 'TestApp';
-
-if ( $ENV{CAT_BENCHMARK} ) {
-    require Benchmark;
-    Benchmark::timethis( $iters, \&run_tests );
-
-    # new dispatcher:
-    # 11 wallclock secs (10.14 usr +  0.20 sys = 10.34 CPU) @ 15.18/s (n=157)
-    # old dispatcher (r1486):
-    # 11 wallclock secs (10.34 usr +  0.20 sys = 10.54 CPU) @ 13.76/s (n=145)
-}
-else {
-    for ( 1 .. $iters ) {
-        run_tests();
-    }
-}
-
-sub run_tests {
-    run_test_for($_) for @paths;
-}
-
-sub run_test_for {
-    my $test = shift;
-
-    my $path;
-    if (ref $test) {
-        $path = join "/", map uri_escape($_), @$test;
-        $test = join '', @$test;
-    } else {
-        $path = uri_escape($test);
-    }
-    
-    SKIP:
-    {   
-        # Skip %2F, ., [, (, and ) tests on real webservers
-        # Both Apache and lighttpd don't seem to like these
-        if ( $ENV{CATALYST_SERVER} && $path =~ /(?:%2F|\.|%5B|\(|\))/ ) {
-            skip "Skipping $path tests on remote server", 6;
-        }
-
-        my $response;
-
-        ok( $response = request("http://localhost/args/args/$path"), "Requested args for path $path");
-
-        is( $response->content, $test, "$test as args" );
-
-        undef $response;
-
-        ok( $response = request("http://localhost/args/params/$path"), "Requested params for path $path");
-
-        is( $response->content, $test, "$test as params" );
-
-        undef $response;
-
-        if( $test =~ m{/} ) {
-            $test =~ s{/}{}g;
-            $path = uri_escape( $test ); 
-        }
-
-        ok( $response = request("http://localhost/chained/multi_cap/$path/baz"), "Requested capture for path $path");
-
-        is( $response->content, join( ', ', split( //, $test ) ) ."; ", "$test as capture" );
-    }
-}
-
@@ -1,77 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 18;
-use Catalyst::Test 'TestApp';
-
-use Catalyst::Request;
-use HTTP::Headers;
-use HTTP::Request::Common;
-
-{
-    my $creq;
-
-    my $request = POST(
-        'http://localhost/dump/request/',
-        'Content-Type' => 'text/plain',
-        'Content'      => 'Hello Catalyst'
-    );
-
-    ok( my $response = request($request), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    like( $response->content, qr/'Catalyst::Request'/,
-        'Content is a serialized Catalyst::Request' );
-
-    {
-        no strict 'refs';
-        ok(
-            eval '$creq = ' . $response->content,
-            'Unserialize Catalyst::Request'
-        );
-    }
-
-    isa_ok( $creq, 'Catalyst::Request' );
-    is( $creq->method,       'POST',       'Catalyst::Request method' );
-    is( $creq->content_type, 'text/plain', 'Catalyst::Request Content-Type' );
-    is( $creq->content_length, $request->content_length,
-        'Catalyst::Request Content-Length' );
-}
-
-{
-    my $creq;
-
-    my $request = POST(
-        'http://localhost/dump/request/',
-        'Content-Type' => 'text/plain',
-        'Content'      => 'x' x 100_000
-    );
-
-    ok( my $response = request($request), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    like(
-        $response->content,
-        qr/^bless\( .* 'Catalyst::Request' \)$/s,
-        'Content is a serialized Catalyst::Request'
-    );
-
-    {
-        no strict 'refs';
-        ok(
-            eval '$creq = ' . $response->content,
-            'Unserialize Catalyst::Request'
-        );
-    }
-
-    isa_ok( $creq, 'Catalyst::Request' );
-    is( $creq->method,       'POST',       'Catalyst::Request method' );
-    is( $creq->content_type, 'text/plain', 'Catalyst::Request Content-Type' );
-    is( $creq->content_length, $request->content_length,
-        'Catalyst::Request Content-Length' );
-}
@@ -1,45 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 13;
-use Catalyst::Test 'TestApp';
-
-use Catalyst::Request;
-use CGI::Simple::Cookie;
-use HTTP::Headers;
-use HTTP::Request::Common;
-use URI;
-
-{
-    my $creq;
-
-    my $request = GET( 'http://localhost/dump/request',
-        'Cookie' => 'Catalyst=Cool; Cool=Catalyst', );
-
-    ok( my $response = request($request), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    like( $response->content, qr/'Catalyst::Request'/,
-        'Content is a serialized Catalyst::Request' );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    isa_ok( $creq, 'Catalyst::Request' );
-    isa_ok( $creq->cookies->{Catalyst}, 'CGI::Simple::Cookie',
-            'Cookie Catalyst' );
-    is( $creq->cookies->{Catalyst}->name, 'Catalyst', 'Cookie Catalyst name' );
-    is( $creq->cookies->{Catalyst}->value, 'Cool', 'Cookie Catalyst value' );
-    isa_ok( $creq->cookies->{Cool}, 'CGI::Simple::Cookie', 'Cookie Cool' );
-    is( $creq->cookies->{Cool}->name,  'Cool',     'Cookie Cool name' );
-    is( $creq->cookies->{Cool}->value, 'Catalyst', 'Cookie Cool value' );
-
-    my $cookies = {
-        Catalyst => $creq->cookies->{Catalyst},
-        Cool     => $creq->cookies->{Cool}
-    };
-
-    is_deeply( $creq->cookies, $cookies, 'Cookies' );
-}
@@ -1,71 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 17;
-use Catalyst::Test 'TestApp';
-
-use Catalyst::Request;
-use HTTP::Headers;
-use HTTP::Request::Common;
-
-{
-    my $creq;
-
-    my $request = GET( 'http://localhost/dump/request', 
-        'User-Agent'       => 'MyAgen/1.0',
-        'X-Whats-Cool'     => 'Catalyst',
-        'X-Multiple'       => [ 1 .. 5 ],
-        'X-Forwarded-Host' => 'frontend.server.com',
-        'X-Forwarded-For'  => '192.168.1.1, 1.2.3.4',
-    );
- 
-    ok( my $response = request($request), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    like( $response->content, qr/^bless\( .* 'Catalyst::Request' \)$/s, 'Content is a serialized Catalyst::Request' );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    isa_ok( $creq, 'Catalyst::Request' );
-    isa_ok( $creq->headers, 'HTTP::Headers', 'Catalyst::Request->headers' );
-    is( $creq->header('X-Whats-Cool'), $request->header('X-Whats-Cool'), 'Catalyst::Request->header X-Whats-Cool' );
-    
-    { # Test that multiple headers are joined as per RFC 2616 4.2 and RFC 3875 4.1.18
-
-        my $excpected = '1, 2, 3, 4, 5';
-        my $got       = $creq->header('X-Multiple'); # HTTP::Headers is context sensitive, "force" scalar context
-
-        is( $got, $excpected, 'Multiple message-headers are joined as a comma-separated list' );
-    }
-
-    is( $creq->header('User-Agent'), $request->header('User-Agent'), 'Catalyst::Request->header User-Agent' );
-
-    my $host = sprintf( '%s:%d', $request->uri->host, $request->uri->port );
-    is( $creq->header('Host'), $host, 'Catalyst::Request->header Host' );
-
-    SKIP:
-    {
-        if ( $ENV{CATALYST_SERVER} && $ENV{CATALYST_SERVER} !~ /127.0.0.1|localhost/ ) {
-            skip "Using remote server", 2;
-        }
-    
-        is( $creq->base->host, 'frontend.server.com', 'Catalyst::Request proxied base' );
-        is( $creq->address, '1.2.3.4', 'Catalyst::Request proxied address' );
-    }
-
-    SKIP:
-    {
-        if ( $ENV{CATALYST_SERVER} ) {
-            skip "Using remote server", 4;
-        }
-        # test that we can ignore the proxy support
-        TestApp->config->{ignore_frontend_proxy} = 1;
-        ok( $response = request($request), 'Request' );
-        ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-        is( $creq->base, 'http://localhost/', 'Catalyst::Request non-proxied base' );
-        is( $creq->address, '127.0.0.1', 'Catalyst::Request non-proxied address' );
-    }
-}
@@ -1,129 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 35;
-use Catalyst::Test 'TestApp';
-
-use Catalyst::Request;
-use HTTP::Headers;
-use HTTP::Request::Common;
-
-{
-    my $creq;
-
-    my $parameters = { 'a' => [qw(A b C d E f G)], };
-
-    my $query = join( '&', map { 'a=' . $_ } @{ $parameters->{a} } );
-
-    ok( my $response = request("http://localhost/dump/request?$query"),
-        'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    like(
-        $response->content,
-        qr/^bless\( .* 'Catalyst::Request' \)$/s,
-        'Content is a serialized Catalyst::Request'
-    );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    isa_ok( $creq, 'Catalyst::Request' );
-    is( $creq->method, 'GET', 'Catalyst::Request method' );
-    is_deeply( $creq->{parameters}, $parameters,
-        'Catalyst::Request parameters' );
-}
-
-{
-    my $creq;
-    ok( my $response = request("http://localhost/dump/request?q=foo%2bbar"),
-        'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    ok( eval '$creq = ' . $response->content );
-    is $creq->{parameters}->{q}, 'foo+bar', '%2b not double decoded';
-}
-
-{
-    my $creq;
-
-    my $parameters = {
-        'a'     => [qw(A b C d E f G)],
-        '%'     => [ '%', '"', '& - &' ],
-        'blank' => '',
-    };
-
-    my $request = POST(
-        'http://localhost/dump/request/a/b?a=1&a=2&a=3',
-        'Content'      => $parameters,
-        'Content-Type' => 'application/x-www-form-urlencoded'
-    );
-
-    unshift( @{ $parameters->{a} }, 1, 2, 3 );
-
-    ok( my $response = request($request), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    like(
-        $response->content,
-        qr/^bless\( .* 'Catalyst::Request' \)$/s,
-        'Content is a serialized Catalyst::Request'
-    );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    isa_ok( $creq, 'Catalyst::Request' );
-    is( $creq->method, 'POST', 'Catalyst::Request method' );
-    is_deeply( $creq->{parameters}, $parameters,
-        'Catalyst::Request parameters' );
-    is_deeply( $creq->arguments, [qw(a b)], 'Catalyst::Request arguments' );
-    is_deeply( $creq->{uploads}, {}, 'Catalyst::Request uploads' );
-    is_deeply( $creq->cookies,   {}, 'Catalyst::Request cookie' );
-}
-
-# http://dev.catalyst.perl.org/ticket/37
-# multipart/form-data parameters that contain 'http://'
-# was an HTTP::Message bug, but HTTP::Body handles it properly now
-{
-    my $creq;
-
-    my $parameters = {
-        'url'   => 'http://www.google.com',
-        'blank' => '',
-    };
-
-    my $request = POST( 'http://localhost/dump/request',
-        'Content-Type' => 'multipart/form-data',
-        'Content'      => $parameters,
-    );
-
-    ok( my $response = request($request), 'Request' );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    is_deeply( $creq->{parameters}, $parameters, 'Catalyst::Request parameters' );
-}
-
-# raw query string support
-{
-    my $creq;
-    
-    my $parameters = {
-        a     => 1,
-        blank => '',
-    };
-
-    my $request = POST(
-        'http://localhost/dump/request/a/b?query+string',
-        'Content'      => $parameters,
-        'Content-Type' => 'application/x-www-form-urlencoded'
-    );
-    
-    ok( my $response = request($request), 'Request' );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    is( $creq->{uri}->query, 'query+string', 'Catalyst::Request POST query_string' );
-    is( $creq->query_keywords, 'query string', 'Catalyst::Request query_keywords' );
-    is_deeply( $creq->{parameters}, $parameters, 'Catalyst::Request parameters' );
-    
-    ok( $response = request('http://localhost/dump/request/a/b?x=1&y=1&z=1'), 'Request' );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    is( $creq->{uri}->query, 'x=1&y=1&z=1', 'Catalyst::Request GET query_string' );
-}
@@ -1,244 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 75;
-use Catalyst::Test 'TestApp';
-
-use Catalyst::Request;
-use Catalyst::Request::Upload;
-use HTTP::Headers;
-use HTTP::Headers::Util 'split_header_words';
-use HTTP::Request::Common;
-
-{
-    my $creq;
-
-    my $request = POST(
-        'http://localhost/dump/request/',
-        'Content-Type' => 'form-data',
-        'Content'      => [
-            'live_engine_request_cookies.t' =>
-              ["$FindBin::Bin/live_engine_request_cookies.t"],
-            'live_engine_request_headers.t' =>
-              ["$FindBin::Bin/live_engine_request_headers.t"],
-            'live_engine_request_uploads.t' =>
-              ["$FindBin::Bin/live_engine_request_uploads.t"],
-        ]
-    );
-
-    ok( my $response = request($request), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    like(
-        $response->content,
-        qr/^bless\( .* 'Catalyst::Request' \)$/s,
-        'Content is a serialized Catalyst::Request'
-    );
-
-    {
-        no strict 'refs';
-        ok(
-            eval '$creq = ' . $response->content,
-            'Unserialize Catalyst::Request'
-        );
-    }
-
-    isa_ok( $creq, 'Catalyst::Request' );
-    is( $creq->method, 'POST', 'Catalyst::Request method' );
-    is( $creq->content_type, 'multipart/form-data',
-        'Catalyst::Request Content-Type' );
-    is( $creq->content_length, $request->content_length,
-        'Catalyst::Request Content-Length' );
-
-    for my $part ( $request->parts ) {
-
-        my $disposition = $part->header('Content-Disposition');
-        my %parameters  = @{ ( split_header_words($disposition) )[0] };
-
-        my $upload = $creq->{uploads}->{ $parameters{filename} };
-
-        isa_ok( $upload, 'Catalyst::Request::Upload' );
-
-        is( $upload->type, $part->content_type, 'Upload Content-Type' );
-        is( $upload->size, length( $part->content ), 'Upload Content-Length' );
-
-        # make sure upload is accessible via legacy params->{$file}
-        is( $creq->{parameters}->{ $upload->filename },
-            $upload->filename, 'legacy param method ok' );
-
-        ok( !-e $upload->tempname, 'Upload temp file was deleted' );
-    }
-}
-
-{
-    my $creq;
-
-    my $request = POST(
-        'http://localhost/dump/request/',
-        'Content-Type' => 'multipart/form-data',
-        'Content'      => [
-            'testfile' => ["$FindBin::Bin/live_engine_request_cookies.t"],
-            'testfile' => ["$FindBin::Bin/live_engine_request_headers.t"],
-            'testfile' => ["$FindBin::Bin/live_engine_request_uploads.t"],
-        ]
-    );
-
-    ok( my $response = request($request), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    like(
-        $response->content,
-        qr/^bless\( .* 'Catalyst::Request' \)$/s,
-        'Content is a serialized Catalyst::Request'
-    );
-
-    {
-        no strict 'refs';
-        ok(
-            eval '$creq = ' . $response->content,
-            'Unserialize Catalyst::Request'
-        );
-    }
-
-    isa_ok( $creq, 'Catalyst::Request' );
-    is( $creq->method, 'POST', 'Catalyst::Request method' );
-    is( $creq->content_type, 'multipart/form-data',
-        'Catalyst::Request Content-Type' );
-    is( $creq->content_length, $request->content_length,
-        'Catalyst::Request Content-Length' );
-
-    my @parts = $request->parts;
-
-    for ( my $i = 0 ; $i < @parts ; $i++ ) {
-
-        my $part        = $parts[$i];
-        my $disposition = $part->header('Content-Disposition');
-        my %parameters  = @{ ( split_header_words($disposition) )[0] };
-
-        my $upload = $creq->{uploads}->{ $parameters{name} }->[$i];
-
-        isa_ok( $upload, 'Catalyst::Request::Upload' );
-        is( $upload->type, $part->content_type, 'Upload Content-Type' );
-        is( $upload->filename, $parameters{filename}, 'Upload filename' );
-        is( $upload->size, length( $part->content ), 'Upload Content-Length' );
-
-        ok( !-e $upload->tempname, 'Upload temp file was deleted' );
-    }
-}
-
-{
-    my $creq;
-
-    my $request = POST(
-        'http://localhost/engine/request/uploads/slurp',
-        'Content-Type' => 'multipart/form-data',
-        'Content'      =>
-          [ 'slurp' => ["$FindBin::Bin/live_engine_request_uploads.t"], ]
-    );
-
-    ok( my $response = request($request), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    is( $response->content, ( $request->parts )[0]->content, 'Content' );
-}
-
-{
-    my $request = POST(
-        'http://localhost/dump/request',
-        'Content-Type' => 'multipart/form-data',
-        'Content'      =>
-          [ 'file' => ["$FindBin::Bin/catalyst_130pix.gif"], ]
-    );
-
-    # LWP will auto-correct Content-Length when using a remote server
-    SKIP:
-    {
-        if ( $ENV{CATALYST_SERVER} ) {
-            skip 'Using remote server', 2;
-        }
-
-        # Sending wrong Content-Length here and see if subequent requests fail
-        $request->header('Content-Length' => $request->header('Content-Length') + 1);
-
-        ok( my $response = request($request), 'Request' );
-        ok( !$response->is_success, 'Response Error' );
-    }
-
-    $request = POST(
-        'http://localhost/dump/request',
-        'Content-Type' => 'multipart/form-data',
-        'Content'      =>
-          [ 'file1' => ["$FindBin::Bin/catalyst_130pix.gif"],
-            'file2' => ["$FindBin::Bin/catalyst_130pix.gif"], ]
-    );
-
-    ok( my $response = request($request), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    like( $response->content, qr/file1 => bless/, 'Upload with name file1');
-    like( $response->content, qr/file2 => bless/, 'Upload with name file2');
-}
-
-{
-    my $creq;
-
-    my $request = POST(
-        'http://localhost/dump/request/',
-        'Content-Type' => 'form-data',
-        'Content'      => [
-            'testfile' => 'textfield value',
-            'testfile' => ["$FindBin::Bin/catalyst_130pix.gif"],
-        ]
-    );
-
-    ok( my $response = request($request), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    like(
-        $response->content,
-        qr/^bless\( .* 'Catalyst::Request' \)$/s,
-        'Content is a serialized Catalyst::Request'
-    );
-
-    {
-        no strict 'refs';
-        ok(
-            eval '$creq = ' . $response->content,
-            'Unserialize Catalyst::Request'
-        );
-    }
-
-    isa_ok( $creq, 'Catalyst::Request' );
-    is( $creq->method, 'POST', 'Catalyst::Request method' );
-    is( $creq->content_type, 'multipart/form-data',
-        'Catalyst::Request Content-Type' );
-    is( $creq->content_length, $request->content_length,
-        'Catalyst::Request Content-Length' );
-
-    my $param = $creq->{parameters}->{testfile};
-
-    ok( @$param == 2, '2 values' );
-    is( $param->[0], 'textfield value', 'correct value' );
-    like( $param->[1], qr/\Qcatalyst_130pix.gif/, 'filename' );
-
-    for my $part ( $request->parts ) {
-
-        my $disposition = $part->header('Content-Disposition');
-        my %parameters  = @{ ( split_header_words($disposition) )[0] };
-
-        next unless exists $parameters{filename};
-
-        my $upload = $creq->{uploads}->{ $parameters{name} };
-
-        isa_ok( $upload, 'Catalyst::Request::Upload' );
-
-        is( $upload->type, $part->content_type, 'Upload Content-Type' );
-        is( $upload->size, length( $part->content ), 'Upload Content-Length' );
-        is( $upload->filename, 'catalyst_130pix.gif' );
-    }
-}
@@ -1,121 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 49;
-use Catalyst::Test 'TestApp';
-use Catalyst::Request;
-
-my $creq;
-
-# test that the path can be changed
-{
-    ok( my $response = request('http://localhost/engine/request/uri/change_path'), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    like( $creq->uri, qr{/my/app/lives/here$}, 'URI contains new path' );
-}
-
-# test that path properly removes the base location
-{
-    ok( my $response = request('http://localhost/engine/request/uri/change_base'), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    like( $creq->base, qr{/new/location}, 'Base URI contains new location' );
-    is( $creq->path, 'engine/request/uri/change_base', 'URI contains correct path' );
-}
-
-# test that base + path is correct
-{
-    ok( my $response = request('http://localhost/engine/request/uri'), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    is( $creq->base . $creq->path, $creq->uri, 'Base + Path ok' );
-}
-
-# test base is correct for HTTPS URLs
-SKIP:
-{
-    if ( $ENV{CATALYST_SERVER} ) {
-        skip 'Using remote server', 5;
-    }
-    
-    local $ENV{HTTPS} = 'on';
-    ok( my $response = request('https://localhost/engine/request/uri'), 'HTTPS Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    is( $creq->base, 'https://localhost/', 'HTTPS base ok' );
-    is( $creq->uri, 'https://localhost/engine/request/uri', 'HTTPS uri ok' );
-}
-
-# test that we can use semi-colons as separators
-{
-    my $parameters = {
-        a => [ qw/1 2/ ],
-        b => 3,
-    };
-    
-    ok( my $response = request('http://localhost/engine/request/uri?a=1;a=2;b=3'), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    is( $creq->{uri}->query, 'a=1;a=2;b=3', 'Query string ok' );
-    is_deeply( $creq->{parameters}, $parameters, 'Parameters ok' );
-}
-
-# test that query params are unescaped properly
-{
-    ok( my $response = request('http://localhost/engine/request/uri?text=Catalyst%20Rocks'), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    ok( eval '$creq = ' . $response->content, 'Unserialize Catalyst::Request' );
-    is( $creq->{uri}->query, 'text=Catalyst%20Rocks', 'Query string ok' );
-    is( $creq->{parameters}->{text}, 'Catalyst Rocks', 'Unescaped param ok' );
-}
-
-# test that uri_with adds params
-{
-    ok( my $response = request('http://localhost/engine/request/uri/uri_with'), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    ok( !defined $response->header( 'X-Catalyst-Param-a' ), 'param "a" ok' );
-    is( $response->header( 'X-Catalyst-Param-b' ), '1', 'param "b" ok' );
-}
-
-# test that uri_with adds params (and preserves)
-{
-    ok( my $response = request('http://localhost/engine/request/uri/uri_with?a=1'), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->header( 'X-Catalyst-Param-a' ), '1', 'param "a" ok' );
-    is( $response->header( 'X-Catalyst-Param-b' ), '1', 'param "b" ok' );
-}
-
-# test that uri_with replaces params (and preserves)
-{
-    ok( my $response = request('http://localhost/engine/request/uri/uri_with?a=1&b=2'), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->header( 'X-Catalyst-Param-a' ), '1', 'param "a" ok' );
-    is( $response->header( 'X-Catalyst-Param-b' ), '1', 'param "b" ok' );
-}
-
-# test that uri_with replaces params (and preserves)
-{
-    ok( my $response = request('http://localhost/engine/request/uri/uri_with_object'), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    like( $response->header( 'X-Catalyst-Param-a' ), qr(https?://localhost[^/]*/), 'param "a" ok' );
-}
-
-# test that uri_with is utf8 safe
-{
-    ok( my $response = request("http://localhost/engine/request/uri/uri_with_utf8"), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    like( $response->header( 'X-Catalyst-uri-with' ), qr/%E2%98%A0$/, 'uri_with ok' );
-}
-
-# test with undef -- no warnings should be thrown
-{
-    ok( my $response = request("http://localhost/engine/request/uri/uri_with_undef"), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->header( 'X-Catalyst-warnings' ), 0, 'no warnings emitted' );
-}
@@ -1,73 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 15;
-use Catalyst::Test 'TestApp';
-use HTTP::Headers::Util 'split_header_words';
-
-my $expected = {
-    Catalyst => [qw|Catalyst Cool path /bah|],
-    Cool     => [qw|Cool Catalyst path /|]
-};
-
-{
-    ok( my $response = request('http://localhost/engine/response/cookies/one'),
-        'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    is( $response->header('X-Catalyst-Action'),
-        'engine/response/cookies/one', 'Test Action' );
-
-    my $cookies = {};
-
-    for my $string ( $response->header('Set-Cookie') ) {
-        my $cookie = [ split_header_words $string];
-        $cookies->{ $cookie->[0]->[0] } = $cookie->[0];
-    }
-
-    is_deeply( $cookies, $expected, 'Response Cookies' );
-}
-
-{
-    ok( my $response = request('http://localhost/engine/response/cookies/two'),
-        'Request' );
-    ok( $response->is_redirect, 'Response Redirection 3xx' );
-    is( $response->code, 302, 'Response Code' );
-    is( $response->header('X-Catalyst-Action'),
-        'engine/response/cookies/two', 'Test Action' );
-
-    my $cookies = {};
-
-    for my $string ( $response->header('Set-Cookie') ) {
-        my $cookie = [ split_header_words $string];
-        $cookies->{ $cookie->[0]->[0] } = $cookie->[0];
-    }
-
-    is_deeply( $cookies, $expected, 'Response Cookies' );
-}
-
-{
-    ok( my $response = request('http://localhost/engine/response/cookies/three'),
-        'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    is( $response->header('X-Catalyst-Action'),
-        'engine/response/cookies/three', 'Test Action' );
-
-    my $cookies = {};
-
-    for my $string ( $response->header('Set-Cookie') ) {
-        my $cookie = [ split_header_words $string];
-        $cookies->{ $cookie->[0]->[0] } = $cookie->[0];
-    }
-
-    is_deeply( $cookies, {
-        hash => [ qw(hash a&b&c path /) ],
-        this_is_the_real_name => [ qw(this_is_the_real_name foo&bar path /) ], # not "object"
-    }, 'Response Cookies' );
-}
@@ -1,60 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 18;
-use Catalyst::Test 'TestApp';
-
-close STDERR;    # i'm naughty :)
-
-{
-    ok( my $response = request('http://localhost/engine/response/errors/one'),
-        'Request' );
-    ok( $response->is_error, 'Response Server Error 5xx' );
-    is( $response->code,         500,         'Response Code' );
-    is( $response->content_type, 'text/html', 'Response Content-Type' );
-    is( $response->header('X-Catalyst-Action'),
-        'engine/response/errors/one', 'Test Action' );
-    like(
-        $response->header('X-Catalyst-Error'),
-        qr/^Caught exception/,
-        'Catalyst Error'
-    );
-}
-
-{
-    ok( my $response = request('http://localhost/engine/response/errors/two'),
-        'Request' );
-    ok( $response->is_error, 'Response Server Error 5xx' );
-    is( $response->code,         500,         'Response Code' );
-    is( $response->content_type, 'text/html', 'Response Content-Type' );
-    is( $response->header('X-Catalyst-Action'),
-        'engine/response/errors/two', 'Test Action' );
-    like(
-        $response->header('X-Catalyst-Error'),
-        qr/^Couldn't forward to/,
-        'Catalyst Error'
-    );
-}
-
-{
-    ok( my $response = request('http://localhost/engine/response/errors/three'),
-        'Request' );
-    ok( $response->is_error, 'Response Server Error 5xx' );
-    is( $response->code,         500,         'Response Code' );
-    is( $response->content_type, 'text/html', 'Response Content-Type' );
-    is(
-        $response->header('X-Catalyst-Action'),
-        'engine/response/errors/three',
-        'Test Action'
-    );
-    like(
-        $response->header('X-Catalyst-Error'),
-        qr/I'm going to die!/,
-        'Catalyst Error'
-    );
-}
@@ -1,58 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 18;
-use Catalyst::Test 'TestApp';
-use HTTP::Request::Common;
-
-my $content_length;
-
-foreach my $method qw(HEAD GET) {
-    my $expected = join( ', ', 1 .. 10 );
-
-    my $request = HTTP::Request::Common->can($method)
-        ->( 'http://localhost/engine/response/headers/one' );
-
-    ok( my $response = request($request), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->code, 200, 'Response Code' );
-    is( $response->header('X-Catalyst-Action'),
-        'engine/response/headers/one', 'Test Action' );
-    is( $response->header('X-Header-Catalyst'),
-        'Cool', 'Response Header X-Header-Catalyst' );
-    is( $response->header('X-Header-Cool'),
-        'Catalyst', 'Response Header X-Header-Cool' );
-    is( $response->header('X-Header-Numbers'),
-        $expected, 'Response Header X-Header-Numbers' );
-
-    use bytes;
-    if ( $method eq 'HEAD' ) {
-        $content_length = $response->header('Content-Length');
-        ok( $content_length > 0, 'Response Header Content-Length' );
-        is( length($response->content),
-            0,
-            'HEAD method content is empty' );
-    }
-    elsif ( $method eq 'GET' ) {
-        # method name is echo'd back in content-body, which
-        # accounts for difference in content length.  In normal
-        # cases the Content-Length should be the same regardless
-        # of if its a GET or HEAD request.
-        SKIP:
-        {
-            if ( $ENV{CATALYST_SERVER} ) {
-                skip "Using remote server", 2;
-            }
-            is( $response->header('Content-Length'),
-                $content_length - 1, 'Response Header Content-Length' );
-            is( length($response->content),
-                $response->header('Content-Length'),
-                'GET method content' );
-        }
-    }
-}
@@ -1,27 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 6;
-use Catalyst::Test 'TestApp';
-
-# phaylon noticed that refactored was truncating output on large images.
-# This test tests 100K and 1M output content.
-
-my $expected = {
-    one => 'x' x (100 * 1024),
-    two => 'y' x (1024 * 1024),
-};
-
-for my $action ( keys %{$expected} ) {
-    ok( my $response = request('http://localhost/engine/response/large/' . $action ),
-        'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    
-    is( length( $response->content ), length( $expected->{$action} ), 'Length OK' );
-}
-
@@ -1,48 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 26;
-use Catalyst::Test 'TestApp';
-
-{
-    ok( my $response = request('http://localhost/engine/response/redirect/one'), 'Request' );
-    ok( $response->is_redirect, 'Response Redirection 3xx' );
-    is( $response->code, 302, 'Response Code' );
-    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/one', 'Test Action' );
-    is( $response->header('Location'), '/test/writing/is/boring', 'Response Header Location' );
-    ok( $response->header('Content-Length'), '302 Redirect contains Content-Length' );
-    ok( $response->content, '302 Redirect contains a response body' );
-}
-
-{
-    ok( my $response = request('http://localhost/engine/response/redirect/two'), 'Request' );
-    ok( $response->is_redirect, 'Response Redirection 3xx' );
-    is( $response->code, 302, 'Response Code' );
-    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/two', 'Test Action' );
-    is( $response->header('Location'), 'http://www.google.com/', 'Response Header Location' );
-}
-
-{
-    ok( my $response = request('http://localhost/engine/response/redirect/three'), 'Request' );
-    ok( $response->is_redirect, 'Response Redirection 3xx' );
-    is( $response->code, 301, 'Response Code' );
-    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/three', 'Test Action' );
-    is( $response->header('Location'), 'http://www.google.com/', 'Response Header Location' );
-    ok( $response->header('Content-Length'), '301 Redirect contains Content-Length' );
-    ok( $response->content, '301 Redirect contains a response body' );
-}
-
-{
-    ok( my $response = request('http://localhost/engine/response/redirect/four'), 'Request' );
-    ok( $response->is_redirect, 'Response Redirection 3xx' );
-    is( $response->code, 307, 'Response Code' );
-    is( $response->header('X-Catalyst-Action'), 'engine/response/redirect/four', 'Test Action' );
-    is( $response->header('Location'), 'http://www.google.com/', 'Response Header Location' );
-    ok( $response->header('Content-Length'), '307 Redirect contains Content-Length' );
-    ok( $response->content, '307 Redirect contains a response body' );
-}
@@ -1,55 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 30;
-use Catalyst::Test 'TestApp';
-
-{
-    ok( my $response = request('http://localhost/engine/response/status/s200'), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    is( $response->code, 200, 'Response Code' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s200', 'Test Action' );
-    like( $response->content, qr/^200/, 'Response Content' );
-}
-
-{
-    ok( my $response = request('http://localhost/engine/response/status/s400'), 'Request' );
-    ok( $response->is_error, 'Response Client Error 4xx' );
-    is( $response->code, 400, 'Response Code' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s400', 'Test Action' );
-    like( $response->content, qr/^400/, 'Response Content' );
-}
-
-{
-    ok( my $response = request('http://localhost/engine/response/status/s403'), 'Request' );
-    ok( $response->is_error, 'Response Client Error 4xx' );
-    is( $response->code, 403, 'Response Code' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s403', 'Test Action' );
-    like( $response->content, qr/^403/, 'Response Content' );
-}
-
-{
-    ok( my $response = request('http://localhost/engine/response/status/s404'), 'Request' );
-    ok( $response->is_error, 'Response Client Error 4xx' );
-    is( $response->code, 404, 'Response Code' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s404', 'Test Action' );
-    like( $response->content, qr/^404/, 'Response Content' );
-}
-
-{
-    ok( my $response = request('http://localhost/engine/response/status/s500'), 'Request' );
-    ok( $response->is_error, 'Response Server Error 5xx' );
-    is( $response->code, 500, 'Response Code' );
-    is( $response->content_type, 'text/plain', 'Response Content-Type' );
-    is( $response->header('X-Catalyst-Action'), 'engine/response/status/s500', 'Test Action' );
-    like( $response->content, qr/^500/, 'Response Content' );
-}
@@ -1,19 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 1;
-use Catalyst::Test 'TestApp';
-
-SKIP:
-{
-    if ( $ENV{CATALYST_SERVER} ) {
-        skip "Using remote server", 1;
-    }
-    # Allow overriding automatic root.
-    is( TestApp->config->{root}, '/some/dir' );
-}
@@ -1,16 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 2;
-use Catalyst::Test 'TestApp';
-
-{
-  # Allow overriding automatic root.
-    ok( my $response = request('http://localhost/engine/response/headers/one'), 'Request' );
-    is( $response->header('X-Catalyst-Plugin-Setup'), '1' );
-}
@@ -1,60 +0,0 @@
-#!/usr/bin/perl
-# live_fork.t 
-# Copyright (c) 2006 Jonathan Rockway <jrockway@cpan.org>
-
-=head1 SYNOPSIS
-
-Tests if Catalyst can fork/exec other processes successfully
-
-=cut
-use strict;
-use warnings;
-use Test::More;
-use YAML;
-use FindBin;
-use lib "$FindBin::Bin/lib";
-use Catalyst::Test qw(TestApp);
-
-plan skip_all => 'Using remote server'
-    if $ENV{CATALYST_SERVER};
-    
-plan skip_all => 'Skipping fork tests: no /bin/ls'
-    if !-e '/bin/ls'; # see if /bin/ls exists
-    
-plan tests => 13; # otherwise
-
-{
-  system:
-    ok(my $result = get('/fork/system/%2Fbin%2Fls'), 'system');
-    my @result = split /$/m, $result;
-    $result = join q{}, @result[-4..-1];
-    
-    my $result_ref = eval { Load($result) };
-    ok($result_ref, 'is YAML');
-    is($result_ref->{result}, 0, 'exited OK');
-}
-
-{ 
-  backticks:
-    ok(my $result = get('/fork/backticks/%2Fbin%2Fls'), '`backticks`');
-    my @result = split /$/m, $result;
-    $result = join q{}, @result[-4..-1];
-    
-    my $result_ref = eval { Load($result) };
-    ok($result_ref, 'is YAML');
-    is($result_ref->{code}, 0, 'exited successfully');
-    like($result_ref->{result}, qr{^/bin/ls[^:]}, 'contains ^/bin/ls$');
-    like($result_ref->{result}, qr{\n.*\n}m, 'contains two newlines');
-}
-{ 
-  fork:
-    ok(my $result = get('/fork/fork'), 'fork');
-    my @result = split /$/m, $result;
-    $result = join q{}, @result[-4..-1];
-    
-    my $result_ref = eval { Load($result) };
-    ok($result_ref, 'is YAML');
-    isnt($result_ref->{pid}, 0, q{fork's "pid" wasn't 0});
-    isnt($result_ref->{pid}, $$, 'fork got a new pid');
-    is($result_ref->{result}, 'ok', 'fork was effective');
-}
@@ -1,23 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 3;
-use Catalyst::Test 'TestApp';
-
-SKIP:
-{
-    # Net::HTTP::Methods crashes when talking to a remote server because this
-    # test causes a very long header line to be sent
-    if ( $ENV{CATALYST_SERVER} ) {
-        skip 'Using remote server', 3;
-    }
-
-    ok( my $response = request('http://localhost/loop_test'), 'Request' );
-    ok( $response->is_success, 'Response Successful 2xx' );
-    ok( $response->header('X-Class-Forward-Test-Method'), 'Loop OK' );
-}
@@ -1,27 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 5;
-use Catalyst::Test 'TestApp';
-
-my @expected = qw[
-  Catalyst::Plugin::Test::Errors
-  Catalyst::Plugin::Test::Headers
-  Catalyst::Plugin::Test::Inline
-  Catalyst::Plugin::Test::Plugin
-  TestApp::Plugin::FullyQualified
-];
-
-my $expected = join( ", ", @expected );
-
-ok( my $response = request('http://localhost/dump/request'), 'Request' );
-ok( $response->is_success, 'Response Successful 2xx' );
-is( $response->content_type, 'text/plain', 'Response Content-Type' );
-like( $response->content, qr/'Catalyst::Request'/,
-    'Content is a serialized Catalyst::Request' );
-is( $response->header('X-Catalyst-Plugins'), $expected, 'Loaded plugins' );
@@ -1,81 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 28;
-use Catalyst::Test 'TestApp';
-use Data::Dumper;
-
-local $^W = 0;
-
-my $uri_base = 'http://localhost/priorities';
-my @tests = (
-
-    #   Simple
-    'Regex vs. Local',      { path => '/re_vs_loc',      expect => 'local' },
-    'Regex vs. LocalRegex', { path => '/re_vs_locre',    expect => 'regex' },
-    'Regex vs. Path',       { path => '/re_vs_path',     expect => 'path' },
-    'Local vs. LocalRegex', { path => '/loc_vs_locre',   expect => 'local' },
-    'Local vs. Path 1',     { path => '/loc_vs_path1',   expect => 'local' },
-    'Local vs. Path 2',     { path => '/loc_vs_path2',   expect => 'path' },
-    'Path  vs. LocalRegex', { path => '/path_vs_locre',  expect => 'path' },
-
-    #   index
-    'index vs. Regex',      { path => '/re_vs_index',    expect => 'index' },
-    'index vs. Local',      { path => '/loc_vs_index',   expect => 'index' },
-    'index vs. LocalRegex', { path => '/locre_vs_index', expect => 'index' },
-    'index vs. Path',       { path => '/path_vs_index',  expect => 'index' },
-
-    'multimethod zero',     { path => '/multimethod',    expect => 'zero' },
-    'multimethod one',      { path => '/multimethod/1',  expect => 'one 1' },
-    'multimethod two',      { path => '/multimethod/1/2',
-                                                         expect => 'two 1 2' },
-);
-
-while ( @tests ) {
-
-    my $name = shift @tests;
-    my $data = shift @tests;
-
-    #   Run tests for path with trailing slash and without
-  SKIP: for my $req_uri 
-    ( 
-        join( '' => $uri_base, $data->{ path } ),      # Without trailing path
-        join( '' => $uri_base, $data->{ path }, '/' ), # With trailing path
-    ) {
-        my $end_slash = ( $req_uri =~ qr(/$) ? 1 : 0 );
-
-        #   use slash_expect argument if URI ends with slash 
-        #   and the slash_expect argument is defined
-        my $expect = $data->{ expect } || '';
-        if ( $end_slash and exists $data->{ slash_expect } ) {
-            $expect = $data->{ slash_expect };
-        }
-
-        #   Call the URI on the TestApp
-        my $response = request( $req_uri );
-
-        #   Leave expect out to see the result
-        unless ( $expect ) {
-            skip 'Nothing expected, winner is ' . $response->content, 1;
-        }
-
-        #   Show error if response was no success
-        if ( not $response->is_success ) {
-            diag 'Error: ' . $response->headers->{ 'x-catalyst-error' };
-        }
-
-        #   Test if content matches expectations.
-        #   TODO This might flood the screen with the catalyst please-come-later
-        #        page. So I don't know it is a good idea.
-        is( $response->content, $expect,
-            "$name: @{[ $data->{ expect } ]} wins"
-            . ( $end_slash ? ' (trailing slash)' : '' )
-        );
-    }
-}
-
@@ -1,25 +0,0 @@
-#!perl
-
-use strict;
-use warnings;
-
-use FindBin;
-use lib "$FindBin::Bin/lib";
-
-use Test::More tests => 3;
-use Catalyst::Test 'TestApp';
-
-local $^W = 0;
-
-SKIP:
-{
-    # Net::HTTP::Methods crashes when talking to a remote server because this
-    # test causes a very long header line to be sent
-    if ( $ENV{CATALYST_SERVER} ) {
-        skip 'Using remote server', 3;
-    }
-
-    ok( my $response = request('http://localhost/recursion_test'), 'Request' );
-    ok( !$response->is_success, 'Response Not Successful' );
-    is( $response->header('X-Catalyst-Error'), 'Deep recursion detected calling "/recursion_test"', 'Deep Recursion Detected' );
-}